怎样建设自己的视频网站,静态宠物网站设计论文,可以做猫头像的网站,厦门外贸网站seo属性填充
属性填充只有 3 种方式 根据名称填充 根据类型填充 思考什么时候会出现呢#xff1f;#xff1f;#xff1f; 多见于第三方框架与 Spring集成#xff0c;举例#xff1a;Mybatis 与 Spring集成#xff0c;把 Mapper 接口注册为 BeanDefinition 时候就指定了自…属性填充
属性填充只有 3 种方式 根据名称填充 根据类型填充 思考什么时候会出现呢 多见于第三方框架与 Spring集成举例Mybatis 与 Spring集成把 Mapper 接口注册为 BeanDefinition 时候就指定了自动注入模式为『 按类型注入 』 // 代码位置org.mybatis.spring.mapper.ClassPathMapperScanner#processBeanDefinitions方法
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);后置处理器基本近似认为是 AutowiredAnnotationBeanPostProcessor 类 多见于自己开发的时候如通过注解Autowired 注入或通过注解Value 注入
1. 总体流程
protected void populateBean(String beanName, RootBeanDefinition mbd, Nullable BeanWrapper bw) {boolean continueWithPropertyPopulation true;// 1 应用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法if (!mbd.isSynthetic() hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {continueWithPropertyPopulation false;break;}}}}if (!continueWithPropertyPopulation) {return;}PropertyValues pvs (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// 2 根据名称自动注入 或者 根据类型自动注入if (mbd.getResolvedAutowireMode() AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable// 2.1 根据名称添加属性值if (mbd.getResolvedAutowireMode() AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable// 2.2 根据类型添加属性值if (mbd.getResolvedAutowireMode() AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs newPvs;}boolean hasInstAwareBpps hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck (mbd.getDependencyCheck() ! AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds null;if (hasInstAwareBpps) {if (pvs null) {pvs mbd.getPropertyValues();}// 3 应用InstantiationAwareBeanPostProcessor的postProcessProperties方法for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp (InstantiationAwareBeanPostProcessor) bp;PropertyValues pvsToUse ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse null) {if (filteredPds null) {filteredPds filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse null) {return;}}pvs pvsToUse;}}}// 4 设置属性值if (pvs ! null) {applyPropertyValues(beanName, mbd, bw, pvs);}
}
1 处应用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法在实例化之后是否继续处理一般都会继续处理2 处根据名称 或 类型自动注入 2.1 处根据名称自动注入重点分析2.2 处根据类型自动注入重点分析 3 处应用InstantiationAwareBeanPostProcessor的postProcessProperties方法一般的就用应用 AutowiredAnnotationBeanPostProcessor 完成 Autowired 或 Value 注解的处理4 处这里 pvs 变量已经是得到的值了这里只需要把值设置到 bw 实例中
2. 各种类型的注入
结论无论是哪一种类型的注入最后都会调用 getBean 方法下面的分析只是简单的说明下如何一步一步调用到 getBean 方法的
2.1 按名称填充autowireByName方法
总结这个直接调用 getBean 方法很简单很好
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {// 1 用内省机制查找需要注入的属性String[] propertyNames unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {if (containsBean(propertyName)) {// 2 既然是使用根据名称注入那么简单了直接 getBean(String) 方法Object bean getBean(propertyName);// 3 添加到 pvs 中返回后设置到pvs.add(propertyName, bean);registerDependentBean(propertyName, beanName);}}
}1 处 用内省机制查找需要注入的属性我们重点查看 如何用内省机制查找属性 protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {SetString result new TreeSet();PropertyValues pvs mbd.getPropertyValues();// 1、内省机制查找属性PropertyDescriptor[] pds bw.getPropertyDescriptors();for (PropertyDescriptor pd : pds) {// 2 并不是所有的属性都需要注入所以要做过滤过滤条件要有 write 方法不是简单属性而是我们常见的需要注入的属性pvs 不包含if (pd.getWriteMethod() ! null !isExcludedFromDependencyCheck(pd) !pvs.contains(pd.getName()) !BeanUtils.isSimpleProperty(pd.getPropertyType())) {result.add(pd.getName());}}return StringUtils.toStringArray(result);
}结果一些代码会来到如下方法 private CachedIntrospectionResults(Class? beanClass) throws BeansException {// 1 内省机制得到 BeanInfo 对象this.beanInfo getBeanInfo(beanClass);this.propertyDescriptorCache new LinkedHashMap();// 2 内省机制获取属性PropertyDescriptor[] pds this.beanInfo.getPropertyDescriptors();for (PropertyDescriptor pd : pds) {pd buildGenericTypeAwarePropertyDescriptor(beanClass, pd);this.propertyDescriptorCache.put(pd.getName(), pd);}// 3 循环处理父接口啊Class? currClass beanClass;while (currClass ! null currClass ! Object.class) {introspectInterfaces(beanClass, currClass);currClass currClass.getSuperclass();}}1 处使用内省机制获取到 beanClass 的 BeanInfo 信息 内省机制Introspector.getBeanInfo(beanClass) 2 处获取属性会获取到父类的所有属性 3 处循环处理父接口啊为什么不处理父类因为不需要处理内省机制获取属性已经包含了父类的属性 2 处 因为是使用名称注入那么直接用属性的名称然后调用 getBean(String) 方法 3 处把 bean 设置到 pvs 中返回交由主方法调用 setXxx 方法把数据设置到目标中
2.2 按类型填充autowireByType方法
跟按名称注入大致一样比它略多几个步骤多一个解析依赖代码如下
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {TypeConverter converter getCustomTypeConverter();if (converter null) {converter bw;}SetString autowiredBeanNames new LinkedHashSet(4);// 1 内省机制查找注入属性String[] propertyNames unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {PropertyDescriptor pd bw.getPropertyDescriptor(propertyName);if (Object.class ! pd.getPropertyType()) {MethodParameter methodParam BeanUtils.getWriteMethodParameter(pd);boolean eager !PriorityOrdered.class.isInstance(bw.getWrappedInstance());DependencyDescriptor desc new AutowireByTypeDependencyDescriptor(methodParam, eager);// 2 解析依赖重点方法Object autowiredArgument resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument ! null) {pvs.add(propertyName, autowiredArgument);}}}
}1 处用内省机制查找注入的属性的 unsatisfiedNonSimpleProperties 方法同前面的『 按名称填充autowireByName方法 』略 2 处重点分析解析依赖 resolveDependency 方法完成依赖解析其实也就是最后调用 getBean 方法 public Object resolveDependency(DependencyDescriptor descriptor, Nullable String requestingBeanName,Nullable SetString autowiredBeanNames, Nullable TypeConverter typeConverter) throws BeansException {// 解析依赖result doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);return result;
}public Object doResolveDependency(DependencyDescriptor descriptor, Nullable String beanName,Nullable SetString autowiredBeanNames, Nullable TypeConverter typeConverter) throws BeansException {InjectionPoint previousInjectionPoint ConstructorResolver.setCurrentInjectionPoint(descriptor);try {// 1 如果注入的类型是 Array、List、Map 等集合类型Object multipleBeans resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);if (multipleBeans ! null) {return multipleBeans;}// 2 注入的不是集合类型但可能匹配了多个MapString, Object matchingBeans findAutowireCandidates(beanName, type, descriptor);if (matchingBeans.isEmpty()) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}return null;}if (matchingBeans.size() 1) {// 2.1 类型匹配了多个那么就要决定使用哪一个如在Primary and Priority就会出现这种情况autowiredBeanName determineAutowireCandidate(matchingBeans, descriptor);instanceCandidate matchingBeans.get(autowiredBeanName);}else {// 2.2 刚好匹配一个更多的是这种情况Map.EntryString, Object entry matchingBeans.entrySet().iterator().next();autowiredBeanName entry.getKey();instanceCandidate entry.getValue();}if (autowiredBeanNames ! null) {autowiredBeanNames.add(autowiredBeanName);}if (instanceCandidate instanceof Class) {// 3 解析候选值这里会调用 getBean 方法instanceCandidate descriptor.resolveCandidate(autowiredBeanName, type, this);}Object result instanceCandidate;// 4 返回 getBean 方法结果return result;}finally {ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);}
}1 处处理集合类型的注入如 Array、List、Map等2 处处理单个注入但是也可能会匹配到多个此时就需要考虑优先级选择出一个如 Primary 注解3 处调用 getBean 方法完成实际的依赖注入4 处返回注入的结果 public Object resolveCandidate(String beanName, Class? requiredType, BeanFactory beanFactory)throws BeansException {// 终于看到我们想要看的 getBean 方法了return beanFactory.getBean(beanName);
}2.3 AutowiredAnnotationBeanPostProcessor的postProcessProperties方法
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {// 1 发现 Autowired 元数据InjectionMetadata metadata findAutowiringMetadata(beanName, bean.getClass(), pvs);// 2 执行实际注入metadata.inject(bean, beanName, pvs);return pvs;
}1 处查找 beanClass 中的Autowired 元数据信息 private InjectionMetadata buildAutowiringMetadata(final Class? clazz) {ListInjectionMetadata.InjectedElement elements new ArrayList();Class? targetClass clazz;do {final ListInjectionMetadata.InjectedElement currElements new ArrayList();// 1 查找本地字段ReflectionUtils.doWithLocalFields(targetClass, field - {// 是不是有Autowired 或 Value 这些注解AnnotationAttributes ann findAutowiredAnnotation(field);if (ann ! null) {boolean required determineRequiredStatus(ann);currElements.add(new AutowiredFieldElement(field, required));}});// 2 查找本地方法ReflectionUtils.doWithLocalMethods(targetClass, method - {// 是不是有Autowired 或 Value 这些注解Method bridgedMethod BridgeMethodResolver.findBridgedMethod(method);if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {return;}AnnotationAttributes ann findAutowiredAnnotation(bridgedMethod);if (ann ! null method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {boolean required determineRequiredStatus(ann);PropertyDescriptor pd BeanUtils.findPropertyForMethod(bridgedMethod, clazz);currElements.add(new AutowiredMethodElement(method, required, pd));}});// 3 处理父类elements.addAll(0, currElements);targetClass targetClass.getSuperclass();}while (targetClass ! null targetClass ! Object.class);return new InjectionMetadata(clazz, elements);
}1 处处理了本地字段是否包含了指定的注解如果包含则加入到元数据中2 处处理了本地方法是否包含了指定的注解如果包含则加入到元数据中3 处循环处理父类直到全部处理完毕 2 处根据前面得到的InjectionMetadata执行实际的注入最后会调用到 getBean 方法以下简单代码描述如何一步一步调用到 getBean 方法 public void inject(Object target, Nullable String beanName, Nullable PropertyValues pvs) throws Throwable {CollectionInjectedElement checkedElements this.checkedElements;CollectionInjectedElement elementsToIterate (checkedElements ! null ? checkedElements : this.injectedElements);// 循环处理每个注入元数据的注入if (!elementsToIterate.isEmpty()) {for (InjectedElement element : elementsToIterate) {element.inject(target, beanName, pvs);}}
}protected void inject(Object bean, Nullable String beanName, Nullable PropertyValues pvs) throws Throwable {// 1 解析Autowired 依赖value beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);// 2 反射设置字段的值if (value ! null) {ReflectionUtils.makeAccessible(field);field.set(bean, value);}
}1 处依赖解析方法 resolveDependency 同前面的『 按类型填充autowireByType方法 』略 2 处使用了反射设置属性值并没有像autowireByName 或 autowireByType 一样把属性添加到 pvs 中最后才设置属性
3. 属性值设置
略 文章转载自: http://www.morning.fkfyn.cn.gov.cn.fkfyn.cn http://www.morning.gbrps.cn.gov.cn.gbrps.cn http://www.morning.jykzy.cn.gov.cn.jykzy.cn http://www.morning.gwjnm.cn.gov.cn.gwjnm.cn http://www.morning.dhyzr.cn.gov.cn.dhyzr.cn http://www.morning.ktyww.cn.gov.cn.ktyww.cn http://www.morning.hxycm.cn.gov.cn.hxycm.cn http://www.morning.ryfqj.cn.gov.cn.ryfqj.cn http://www.morning.nccyc.cn.gov.cn.nccyc.cn http://www.morning.nngq.cn.gov.cn.nngq.cn http://www.morning.dkzwx.cn.gov.cn.dkzwx.cn http://www.morning.dmfdl.cn.gov.cn.dmfdl.cn http://www.morning.yrbq.cn.gov.cn.yrbq.cn http://www.morning.ggnrt.cn.gov.cn.ggnrt.cn http://www.morning.ykbgs.cn.gov.cn.ykbgs.cn http://www.morning.scrnt.cn.gov.cn.scrnt.cn http://www.morning.jghqc.cn.gov.cn.jghqc.cn http://www.morning.xhqwm.cn.gov.cn.xhqwm.cn http://www.morning.lgwjh.cn.gov.cn.lgwjh.cn http://www.morning.slmbg.cn.gov.cn.slmbg.cn http://www.morning.jmspy.cn.gov.cn.jmspy.cn http://www.morning.jncxr.cn.gov.cn.jncxr.cn http://www.morning.mpyry.cn.gov.cn.mpyry.cn http://www.morning.fsbns.cn.gov.cn.fsbns.cn http://www.morning.gqksd.cn.gov.cn.gqksd.cn http://www.morning.qdxwf.cn.gov.cn.qdxwf.cn http://www.morning.zgnng.cn.gov.cn.zgnng.cn http://www.morning.dpflt.cn.gov.cn.dpflt.cn http://www.morning.nxpqw.cn.gov.cn.nxpqw.cn http://www.morning.hnmbq.cn.gov.cn.hnmbq.cn http://www.morning.rcww.cn.gov.cn.rcww.cn http://www.morning.glkhx.cn.gov.cn.glkhx.cn http://www.morning.jkpnm.cn.gov.cn.jkpnm.cn http://www.morning.gmwqd.cn.gov.cn.gmwqd.cn http://www.morning.tstwx.cn.gov.cn.tstwx.cn http://www.morning.rbktw.cn.gov.cn.rbktw.cn http://www.morning.wyppp.cn.gov.cn.wyppp.cn http://www.morning.ptqds.cn.gov.cn.ptqds.cn http://www.morning.drnfc.cn.gov.cn.drnfc.cn http://www.morning.dlwzm.cn.gov.cn.dlwzm.cn http://www.morning.kbqws.cn.gov.cn.kbqws.cn http://www.morning.xnkh.cn.gov.cn.xnkh.cn http://www.morning.gwsdt.cn.gov.cn.gwsdt.cn http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn http://www.morning.caswellintl.com.gov.cn.caswellintl.com http://www.morning.fslxc.cn.gov.cn.fslxc.cn http://www.morning.wzdjl.cn.gov.cn.wzdjl.cn http://www.morning.qwdlj.cn.gov.cn.qwdlj.cn http://www.morning.wfykn.cn.gov.cn.wfykn.cn http://www.morning.cmhkt.cn.gov.cn.cmhkt.cn http://www.morning.hdzty.cn.gov.cn.hdzty.cn http://www.morning.hfnbr.cn.gov.cn.hfnbr.cn http://www.morning.lhqw.cn.gov.cn.lhqw.cn http://www.morning.dpnhs.cn.gov.cn.dpnhs.cn http://www.morning.txlxr.cn.gov.cn.txlxr.cn http://www.morning.rtbx.cn.gov.cn.rtbx.cn http://www.morning.nlkm.cn.gov.cn.nlkm.cn http://www.morning.lpppg.cn.gov.cn.lpppg.cn http://www.morning.ytbr.cn.gov.cn.ytbr.cn http://www.morning.mhfbp.cn.gov.cn.mhfbp.cn http://www.morning.smwlr.cn.gov.cn.smwlr.cn http://www.morning.ymhzd.cn.gov.cn.ymhzd.cn http://www.morning.tbplf.cn.gov.cn.tbplf.cn http://www.morning.mqdr.cn.gov.cn.mqdr.cn http://www.morning.nyqm.cn.gov.cn.nyqm.cn http://www.morning.kfstq.cn.gov.cn.kfstq.cn http://www.morning.sjwiki.com.gov.cn.sjwiki.com http://www.morning.srndk.cn.gov.cn.srndk.cn http://www.morning.hnhsym.cn.gov.cn.hnhsym.cn http://www.morning.yhwmg.cn.gov.cn.yhwmg.cn http://www.morning.bwqr.cn.gov.cn.bwqr.cn http://www.morning.wcrcy.cn.gov.cn.wcrcy.cn http://www.morning.dywgl.cn.gov.cn.dywgl.cn http://www.morning.gglhj.cn.gov.cn.gglhj.cn http://www.morning.rqnzh.cn.gov.cn.rqnzh.cn http://www.morning.rqgq.cn.gov.cn.rqgq.cn http://www.morning.slwfy.cn.gov.cn.slwfy.cn http://www.morning.rxfgh.cn.gov.cn.rxfgh.cn http://www.morning.lxwjx.cn.gov.cn.lxwjx.cn http://www.morning.zfkxj.cn.gov.cn.zfkxj.cn