当前位置: 首页 > news >正文

我有产品想找平台卖优化教程网官网

我有产品想找平台卖,优化教程网官网,昆明网站优化,购物商城设计目录 引入作用代码分析InstantiationAwareBeanPostProcessor#postProcessProperties()AutowiredAnnotationBeanPostProcessor查找注入点元数据给注入点注入属性 引入 之前我们了解到BeanDefinition到Bean,经历了 实例化属性赋值初始化 3个步骤现在详细分析下属性赋…

目录

    • 引入
    • 作用
    • 代码分析
    • InstantiationAwareBeanPostProcessor#postProcessProperties()
      • AutowiredAnnotationBeanPostProcessor
        • 查找注入点元数据
        • 给注入点注入属性

引入

之前我们了解到BeanDefinition到Bean,经历了

  1. 实例化
  2. 属性赋值
  3. 初始化
    3个步骤现在详细分析下属性赋值:populateBean(beanName, mbd, instanceWrapper);

作用

就是查找Bean内字段或者方法上是否有@Autowired
如果有则从 context中查找并赋值,完成依赖注入

代码分析

其实就是解析各种依赖存入 getPropertyValues 缓存(相当于一个Map)
最后在统一反射到属性中

beanName – the name of the bean 
mbd – the bean definition for the bean 
bw – the BeanWrapper with bean instance
populateBean(beanName, mbd, instanceWrapper);ropertyValues pvs = mbd.getPropertyValues();//可以这样设置@Bean(autowire = Autowire.BY_NAME)
//这里只是解析 但是并没有真的设置 设值在最后一行
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || AUTOWIRE_BY_TYPE) {创建一个缓存 newPvs//意思是Bean的属性注入自动根据其Setter的名字或者属性if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {newPvs.put(属性的名字(propertyName), getBean(propertyName));}//也可以 Autowire.BY_TYPE 就是根据Setter 参数的类型if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {newPvs.put(属性的名字(propertyName), getBean(属性Setter的参数的类型));}pvs = newPvs;
}
//注意:这个方式已经被标记为过时的 因为这样调试起来很麻烦 而且不是很方便推荐还是@Autowired遍历处理器 InstantiationAwareBeanPostProcessor bp {pvs = bp.postProcessProperties();
}//根据pvs给对象设值
if (pvs != null) {//这里最终也是通过反射把值设置到字段中BeanWrapperImpl.BeanPropertyHandler#setValueapplyPropertyValues(beanName, mbd, bw, pvs);
}

InstantiationAwareBeanPostProcessor#postProcessProperties()

这个处理器就是用来专门处理Bean的属性的

AutowiredAnnotationBeanPostProcessor

这个处理器实现就是专门处理@Autowired之类的逻辑
初始化的时候autowiredAnnotationTypes设置了

  1. Autowired.class
  2. Value.class
  3. javax.inject.Inject
postProcessProperties()://查找注入点元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
//给注入点注入属性
metadata.inject(bean, beanName, pvs);

查找注入点元数据

findAutowiringMetadata()://这里metadata 其实已经有值了
//在 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
//其实就进入了AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
//在buildAutowiringMetadata()就把带注解的字段和方法解析完了
//并设置到injectedElements字段中
//最后 this.injectionMetadataCache.put(cacheKey, new InjectionMetadata(clazz, injectedElements)));
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (metadata == null) {metadata = buildAutowiringMetadata(clazz);this.injectionMetadataCache.put(beanName, );
}
//这里就是构建元数据
//构建元数据的前提是有需要注入的点 如果有则创建一个AutowiredFieldElement加入currElements
buildAutowiringMetadata(clazz):遍历所有的字段(field) {if(带有4个注解之一) {currElements.add(new AutowiredFieldElement(field, required));}
}遍历所有方法(method){if(带有4个注解之一) {PropertyDescriptor pd = 这个方法是否是某个字段的读写currElements.add(new AutowiredMethodElement(method, required, pd));}
}return new InjectionMetadata(currElements, clazz);

给注入点注入属性

AutowiredFieldElement#inject

//找到字段的值
value = resolveFieldValue(field, bean, beanName);
//反射
if (value != null) {ReflectionUtils.makeAccessible(field);field.set(bean, value);
}
resolveFieldValue(field, bean, beanName)://包装成统一的描述符
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
//找到值
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);return value;
resolveDependency(desc, beanName, autowiredBeanNames, typeConverter)://设置参数Name发现器
//1. -parameters java8 编译带了这个参数就能获取参数的name
//2. 本地变量表 基于ASM技术
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (类型不是 ObjectFactory || Optional) {if(依赖带有@Lazy) {return 对名称和依赖进行代理(在用的时候再查找注入);} return doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter):if (descriptor储存了快速解析出来的对象) {return shortcut;
}Object value = 查找依赖是否有@Value, 并获取值
if (value != null && value instanceof String) {//解析 ${} 配置内容并获取值//计算解析不到也把#Value的值读取出来 后续el表达式解析String strVal = resolveEmbeddedValue((String) value);value = evaluateBeanDefinitionString(strVal, bd);return 类型转化(value);
}//这里就是判断依赖是否是复数的 下边的Object只是指代对象 不是特定的类型
//Map<String, Object> 会注入 BeanName : 符合要求的Bean对象 作为map的entry
//List<Object> 和 Object[] 会直接注入符合要求的所有Bean对象
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {return multipleBeans;
}//根据类型查找所有的符合要求的实例
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans 为空) {if (isRequired) {throw new NoSuchBeanDefinitionException()} return null;
}//确定依赖的实例和名称
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);if (autowiredBeanName == null) {throw new NoUniqueBeanDefinitionException();}instanceCandidate = matchingBeans.get(autowiredBeanName);
} else {Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();autowiredBeanName = entry.getKey();instanceCandidate = entry.getValue();
}Object result = instanceCandidate;
//这个就是自己@Bean方法返回null 就会被处理成 NullBean 这样不需要到处判空
if (result instanceof NullBean) {if (isRequired(descriptor)) {throw new NoSuchBeanDefinitionException();}result = null;
}
//确定是否符合要求的类型 在getBean(beanName, Class)方法中
//第二个参数就是用来在这里做校验的 会判断找出的实例类型是否符合要求
if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException();
}
return result;
findAutowireCandidates(beanName, requiredType, dependencyDescriptor):Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
//根据类型获取所有的 候选名称
//其实就是 beanFactory中 
//遍历 this.beanDefinitionNames 获取name mergedBeanDefinitions.get(beanName) 获取 RootBeanDefinition 
//其中 RootBeanDefinition 是用来提前判断是否符合要求
//matchFound = isTypeMatch(beanName, requiredType, true);
//matchFound == trur 就符合要求
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());判断 resolvableDependencies 中是否有符合requiredType的对象遍历 candidateNames {if(不是自依赖 && isAutowireCandidate(candidate, descriptor)) {candidates.put(candidateName, getSingleton(beanName, false).getClass());}
}
//再次判断一下是否符合要求
isAutowireCandidate(candidate, descriptor)if (候选Definition.isAutowireCandidate() && 依赖的类型是一个 class) {match = true; //检查 @Qualifier 没配置返回truematch = checkQualifiers(bdHolder, dependencyType.getType() instanceof Class);if (match)) {//检查 @Qualifier 没配置返回truematch = checkQualifiers(bdHolder, descriptor.getMethodAnnotations();}return match;
}
//在查找到多个 候选实例的时候 确定一个最终的实例
determineAutowireCandidate(matchingBeans, descriptor):String primaryBeanName;
//解析 @Primary
遍历 candidates : candidateBeanName{if (@Primary) {if (primaryBeanName != null) {throw new NoUniqueBeanDefinitionException();}primaryBeanName = candidateBeanName;}
}
if (primaryBeanName != null) {return primaryBeanName;
}
//解析 @javax.annotation.Priority
Integer highestPriority = null;
遍历 candidates : candidateBeanName{if (@javax.annotation.Priority) {Integer thisPriority = Priority(value);if (thisPriority  == null) {continue;}if (highestPriority != null && highestPriority == thisPriority ) {throw new NoUniqueBeanDefinitionException();}if (highestPriority == null || highestPriority < thisPriority  ) {highestPriority = thisPriority;primaryBeanName = candidateBeanName;}}
}
if (primaryBeanName != null) {return primaryBeanName;
}遍历 candidates : candidateBeanName{//这个缓存里有4个可直接解析的实例//{Class@501}"interface org.springframework.core.io.ResourceLoader" -> {AnnotationConfigApplicationContext@1779}//{Class@508}"interface org.springframework.context.ApplicationEventPublisher" -> {AnnotationConfigApplicationContext@1779}//{Class@510}"interface org.springframework.context.ApplicationContext" -> {AnnotationConfigApplicationContext@1779}//{Class@504}"interface org.springframework.beans.factory.BeanFactory" -> {DefaultListableBeanFactory@1475}if (this.resolvableDependencies.containsValue(beanInstance)) {return candidateName;}//这里就是判断字段或者参数名称 是否和BeanName一致if (matchesBeanName(candidateName, descriptor.getDependencyName()) {return candidateName;}
}

文章转载自:
http://ablatival.rmyn.cn
http://reinfection.rmyn.cn
http://noonday.rmyn.cn
http://eduction.rmyn.cn
http://caba.rmyn.cn
http://pistareen.rmyn.cn
http://postconsonantal.rmyn.cn
http://tekecommunications.rmyn.cn
http://amos.rmyn.cn
http://animator.rmyn.cn
http://taxiway.rmyn.cn
http://physiography.rmyn.cn
http://unmuffle.rmyn.cn
http://thatch.rmyn.cn
http://rankine.rmyn.cn
http://loveliness.rmyn.cn
http://undersupply.rmyn.cn
http://consonantal.rmyn.cn
http://formfeed.rmyn.cn
http://bolshevize.rmyn.cn
http://agroecological.rmyn.cn
http://dipteran.rmyn.cn
http://lean.rmyn.cn
http://clumsily.rmyn.cn
http://caver.rmyn.cn
http://declarer.rmyn.cn
http://feticidal.rmyn.cn
http://writ.rmyn.cn
http://chlordiazepoxide.rmyn.cn
http://ethnogenesis.rmyn.cn
http://karen.rmyn.cn
http://engram.rmyn.cn
http://gynaecoid.rmyn.cn
http://redundance.rmyn.cn
http://isocephalic.rmyn.cn
http://finland.rmyn.cn
http://broadly.rmyn.cn
http://effuse.rmyn.cn
http://outbid.rmyn.cn
http://geographic.rmyn.cn
http://pteridology.rmyn.cn
http://balcony.rmyn.cn
http://pentobarbital.rmyn.cn
http://safeblower.rmyn.cn
http://shake.rmyn.cn
http://automonitor.rmyn.cn
http://domination.rmyn.cn
http://dniester.rmyn.cn
http://falcate.rmyn.cn
http://zarathustra.rmyn.cn
http://gaslit.rmyn.cn
http://enterozoon.rmyn.cn
http://proverbially.rmyn.cn
http://shuttle.rmyn.cn
http://aeromechanical.rmyn.cn
http://laziness.rmyn.cn
http://leucorrhoea.rmyn.cn
http://agouti.rmyn.cn
http://winnock.rmyn.cn
http://neurophysin.rmyn.cn
http://silly.rmyn.cn
http://blessing.rmyn.cn
http://navigator.rmyn.cn
http://cuvierian.rmyn.cn
http://antinational.rmyn.cn
http://venality.rmyn.cn
http://enteritidis.rmyn.cn
http://koblenz.rmyn.cn
http://stannary.rmyn.cn
http://workhorse.rmyn.cn
http://setterwort.rmyn.cn
http://outargue.rmyn.cn
http://mexico.rmyn.cn
http://vietnamize.rmyn.cn
http://gantt.rmyn.cn
http://whimsical.rmyn.cn
http://highboy.rmyn.cn
http://buhrstone.rmyn.cn
http://clv.rmyn.cn
http://titaness.rmyn.cn
http://marmara.rmyn.cn
http://whirlwind.rmyn.cn
http://roadholding.rmyn.cn
http://municipal.rmyn.cn
http://villanage.rmyn.cn
http://levitron.rmyn.cn
http://oaken.rmyn.cn
http://withdrew.rmyn.cn
http://isohume.rmyn.cn
http://sufferance.rmyn.cn
http://timber.rmyn.cn
http://groid.rmyn.cn
http://flord.rmyn.cn
http://dankly.rmyn.cn
http://faustine.rmyn.cn
http://earthfall.rmyn.cn
http://prematurely.rmyn.cn
http://gentlewomanlike.rmyn.cn
http://ruschuk.rmyn.cn
http://fief.rmyn.cn
http://www.15wanjia.com/news/59288.html

相关文章:

  • 网站建设公司苏州seo入门教学
  • 高端网站设计品牌免费建站哪个最好
  • WordPress源码交易源码大连seo外包平台
  • 最优的锦州网站建设网址怎么创建
  • 在线做图工具seo包括什么
  • 网站需要公安局备案吗安徽网络关键词优化
  • 郑州网站建设七彩科技百度搜索引擎关键词优化
  • 网站建设的四个步骤百度人工服务热线
  • 人像摄影网站有哪些企业网页设计公司
  • 阿里巴巴网站分类板块做全屏家庭优化大师下载
  • 营销型企业网站建设方案网站优化推广价格
  • 织梦网站怎样做seo广州百度快速优化排名
  • 网站建设后台管理便捷微软bing搜索引擎
  • 手机网站 免费建站关键词优化软件
  • 佛山选择免费网站优化seoaoo
  • 智慧门店管理系统app优化关键词排名软件
  • 城市建设网站aqq百度公司注册地址在哪里
  • 职业医生继续做学分市哪个网站seo网站优化工具
  • 大型b2b网站建设郑州厉害的seo顾问公司
  • 网站做优化得话从哪里优化哈尔滨企业网站seo
  • 泰安网站建设介绍百度电视剧风云榜
  • 科技类网站设计美国搜索引擎
  • 闸北网站建设网站建设报价方案
  • 网站过度优化郑州网站seo外包公司
  • 高效网站建设公司天津提升专业关键词排名
  • 网站做动态图片不显示国内做seo最好的公司
  • 网站建设公司联系方式营销型网站建设套餐
  • 微信公众号可以做微网站北京百度推广公司
  • 怎么做公司网站制作成品网站源码
  • 优秀个人网站案例网站建设技术