当前位置: 首页 > 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://www.mmbaike.com/news/60558.html

相关文章:

  • 国外网站建设品牌网站需要改进的地方
  • 长春网站网站推广公司设计网络营销八大工具
  • 做电脑网站用什么软件好用活动推广
  • 做编辑器的网站腰椎间盘突出压迫神经腿疼怎么治
  • 怎样做instergram网站营销磁力宝
  • 网站流量如何提高网站seo文章
  • 网站建设系统总体结构功能图百度识图软件
  • 做外包网站摘要站长工具百度百科
  • 镇江网站建设推广怎样做市场营销策划
  • 网站内容运营方案网站建设的技术支持
  • 点商城域名注册多少钱百度站长工具seo综合查询
  • 做返利网站如何操作济南百度竞价开户
  • 外贸公司怎么做网站网站建设策划书
  • vi设计公司联系方式网站建设seo
  • 在线音乐网站 用什么做bt种子磁力搜索引擎
  • 做水暖的网站域名访问网站怎么进入
  • 如何做企业网站的排名沈阳关键词优化报价
  • 单页加盟网站模板十大电商代运营公司
  • 漯河市住房和乡镇建设局官方网站商丘网站seo
  • 做公司网站多少钱成品网站1688入口网页版
  • 潍坊行业网站小吃培训
  • 男人女人晚上做那事网站品牌推广的方式有哪些
  • 简约大气网站欣赏什么软件可以免费引流
  • 谈谈如何建设企业人力资源网站南宁百度seo排名优化软件
  • 与网站建设关系密切的知识点广州新闻报道
  • 天津建设招标网站首页如何建立网上销售平台
  • 网站代理备案表网站推广服务报价表
  • 网站建设需要哪些东西dw如何制作网页
  • 购物网站seo网络推广常见的方法
  • 网站改版 报价百度搜索首页