范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Spring源码SpringBean的创建过程(14)

  到目前为止,我们知道Spring创建Bean对象有5中方法,分别是: 使用FactoryBean的getObject方法创建 使用BeanPostProcessor的子接口InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法创建 设置BeanDefinition的Supplier属性进行创建 设置BeanDefinition的factory-method进行创建 使用全过程:getBean-->doGetBean-->createBean-->doCreateBean 反射进行创建
  前面4种已经介绍,接下来介绍第5种,我们知道如果使用反射创建,那么必然要知道使用构造函数进行实例化,因为使用构造函数能够将带有参数的设置进去。 SmartInstantiationAwareBeanPostProcessor 接口
  在前面讲过InstantiationAwareBeanPostProcessor 是用来提前实例化对象的,而SmartInstantiationAwareBeanPostProcessor是InstantiationAwareBeanPostProcessor 的接口,他是用来干啥呢?
  在createBeanInstance方法中的源码: // 省略代码.... // 明确构造器从BeanPostProcessor中,对应的是 AutowiredAnnotationBeanPostProcessor // 他是 SmartInstantiationAwareBeanPostProcessor 的子类,使用determineCandidateConstructors进行 // 解析构造函数 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||     mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {   return autowireConstructor(beanName, mbd, ctors, args); } // 省略代码....
  点进去: protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)   throws BeansException {    if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {     for (BeanPostProcessor bp : getBeanPostProcessors()) {       if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {         SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;         // 决定候选的构造函数         Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);         if (ctors != null) {           return ctors;         }       }     }   }   return null; }
  可以看到这个接口是用来解析BeanClass的构造函数的,SmartInstantiationAwareBeanPostProcessor的实现类AutowiredAnnotationBeanPostProcessor,这个类是用来解析确定合适的构造函数,重点解析了@Autowired注解,并且还解析了@Value注解和@Lookup注解。
  当解析出来构造函数之后,那么就调用autowireConstructor方法进行实例化,解析时会new一个构造器解析器ConstructorResolver ,在解析factoryMehod时也是使用的这个类使用的是instantiateUsingFactoryMethod这个方法,并且解析factoryMethod更加复杂,需要判断是否是静态的工厂创建还是实例工厂创建,而自动装配的构造解析相对来说简单一些,使用autowireConstructor方法进行解析。
  最终解析出构造方法和构造参数之后进行实例化: // 使用合适的构造方法和构造参数进行实例化 bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
  实例化: private Object instantiate(   String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {    try {     // 获取实例化策略,一般使用 CglibSubClassingInstantiationStrategy     InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();     if (System.getSecurityManager() != null) {       return AccessController.doPrivileged((PrivilegedAction) () ->                                            strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),                                            this.beanFactory.getAccessControlContext());     }     else {       // 开始实例化       return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);     }   }   catch (Throwable ex) {     throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                     "Bean instantiation via constructor failed", ex);   } }  public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,                           final Constructor<?> ctor, Object... args) {   if (!bd.hasMethodOverrides()) {     if (System.getSecurityManager() != null) {       // use own privileged to change accessibility (when security is on)       AccessController.doPrivileged((PrivilegedAction) () -> {         ReflectionUtils.makeAccessible(ctor);         return null;       });     }     // 实例化类,反射调用     return BeanUtils.instantiateClass(ctor, args);   }   else {     // 如果方法被覆盖,lookup-method 和 replace-method     return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);   } }
  如果前面的解析都没有到Bean,那么就会使用无参构造函数进行解析: // 省略代码.... // Preferred constructors for default construction? // 首选的构造器为默认的创建方式,使用了@Primary注解的为首选的创建对象方式 ctors = mbd.getPreferredConstructors(); if (ctors != null) {   return autowireConstructor(beanName, mbd, ctors, null); }  // No special handling: simply use no-arg constructor. // 调用无参构造函数实例化对象 return instantiateBean(beanName, mbd);
  实例化Bean: protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {   try {     Object beanInstance;     if (System.getSecurityManager() != null) {       beanInstance = AccessController.doPrivileged(         (PrivilegedAction) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),         getAccessControlContext());     }     else {       // 实例化对象,使用反射进行创建       beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);     }     // 创建一个Bean的包装器     BeanWrapper bw = new BeanWrapperImpl(beanInstance);     // 初始化Bean的包装器     initBeanWrapper(bw);     return bw;   }   catch (Throwable ex) {     throw new BeanCreationException(       mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);   } }
  这里可以看到前面使用factoryMethod 和autowireConstructor 解析构造函数进行实例化还是使用无参构造函数进行实例化都是将Bean进行了包装,那这个包装有啥作用呢? BeanWrapper的作用
  我们先来看下前面的方法是怎么创建BeanWrapper的:
  factory-method 解析,ConstructorResolver#instantiateUsingFactoryMethod 方法: public BeanWrapper instantiateUsingFactoryMethod( 			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) { 		// 创建一个Bean的包装器 		BeanWrapperImpl bw = new BeanWrapperImpl(); 		this.beanFactory.initBeanWrapper(bw); 		// factoryBean 		Object factoryBean; 		// factory 工厂类 		Class<?> factoryClass; 		// 标识是否是静态的工厂 		boolean isStatic;         // 省略代码.... }
  SmartInstantiationAwareBeanPostProcessor子类AutowiredAnnotationBeanPostProcessor 解析出构造函数,然后使用ConstructorResolver#autowireConstructor 执行: public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, 			@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { 		// 创建一个包装器 		BeanWrapperImpl bw = new BeanWrapperImpl(); 		// 初始化包装器 		this.beanFactory.initBeanWrapper(bw); 		// 构造函数 		Constructor<?> constructorToUse = null; 		// 构造参数 		ArgumentsHolder argsHolderToUse = null; 		// 需要使用的构造参数 		Object[] argsToUse = null; 		// 明确的构造参数不为空,则赋值给将要执行实例化的构造参数 		if (explicitArgs != null) { 			argsToUse = explicitArgs; 		}         // 省略代码.... }
  最终都是会进行转换服务ConversionService和PropertyEditorRegistry的注册,一个是用来进行属性类型转换的,一个是用来属性值解析的: protected void initBeanWrapper(BeanWrapper bw) {   // 获取转换服务放到bean的包装器中   bw.setConversionService(getConversionService());   // 注册定制的属性编辑器   registerCustomEditors(bw); }
  在前面的文章中,介绍了这两个如何使用,而且还自定义了属性编辑器和类型转换,需要的小伙伴可以去看看:
  https://www.cnblogs.com/redwinter/p/16167214.html 和 https://www.cnblogs.com/redwinter/p/16241328.html
  到这里Bean的实例化就完成了,接着往下看源码: protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)   throws BeanCreationException {    // Instantiate the bean.   BeanWrapper instanceWrapper = null;   // 从缓存中获取FactoryBean的Bean对象   if (mbd.isSingleton()) {     instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);   }   if (instanceWrapper == null) {     // 实例化对象     instanceWrapper = createBeanInstance(beanName, mbd, args);   }   // 从包装器中获取Bean对象   Object bean = instanceWrapper.getWrappedInstance();   // 从包装器中获取Bean类型   Class<?> beanType = instanceWrapper.getWrappedClass();   if (beanType != NullBean.class) {     mbd.resolvedTargetType = beanType;   }    // Allow post-processors to modify the merged bean definition.   synchronized (mbd.postProcessingLock) {     if (!mbd.postProcessed) {       try {         // 合并Bean         applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);       }       catch (Throwable ex) {         throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                         "Post-processing of merged bean definition failed", ex);       }       mbd.postProcessed = true;     }   } }
  点进去: protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {   for (BeanPostProcessor bp : getBeanPostProcessors()) {     if (bp instanceof MergedBeanDefinitionPostProcessor) {       MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;       // 执行合并BeanDefinition       bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);     }   } }
  可以看到这里出现了一个接口MergedBeanDefinitionPostProcessor,这个接口也是BeanPostProcessor的子接口,那他到底是干啥用的呢? MergedBeanDefinitionPostProcessor 接口
  点击发现这个接口的实现类全是跟注解相关的,而最重要的是CommonAnnotationBeanPostProcessor实现类,在构造函数中设置了两个注解:@PostConstruct 和 @PreDestroy ,一个是在初始化完之后调用,一个是容器销毁时调用。CommonAnnotationBeanPostProcessor这个类的父类为InitDestroyAnnotationBeanPostProcessor,用于处理初始化和销毁方法的。
  CommonAnnotationBeanPostProcessor 的构造器: public CommonAnnotationBeanPostProcessor() { 		setOrder(Ordered.LOWEST_PRECEDENCE - 3); 		// 初始化PostConstruct PreDestroy注解 		// 调用父类的方法进行设置 		setInitAnnotationType(PostConstruct.class); 		setDestroyAnnotationType(PreDestroy.class); 		ignoreResourceType("javax.xml.ws.WebServiceContext"); 	}
  CommonAnnotationBeanPostProcessor 合并方法: public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { 		// 调用父类 		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName); 		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null); 		metadata.checkConfigMembers(beanDefinition); 	}
  点击postProcessMergedBeanDefinition方法发现调用了父类的这个方法,然后执行了一个叫查找生命周期元数据的方法findLifecycleMetadata。 public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { 		LifecycleMetadata metadata = findLifecycleMetadata(beanType); 		metadata.checkConfigMembers(beanDefinition); 	}
  查找生命周期的元数据: private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) { 		if (this.lifecycleMetadataCache == null) { 			// Happens after deserialization, during destruction... 			return buildLifecycleMetadata(clazz); 		} 		// Quick check on the concurrent map first, with minimal locking. 		// 查询缓存 		LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz); 		if (metadata == null) { 			synchronized (this.lifecycleMetadataCache) { 				// 再次查询 				metadata = this.lifecycleMetadataCache.get(clazz); 				if (metadata == null) { 					// 没有查询到就去构建生命周期的元数据 					metadata = buildLifecycleMetadata(clazz); 					this.lifecycleMetadataCache.put(clazz, metadata); 				} 				return metadata; 			} 		} 		return metadata; 	}
  构建生命周期元数据: private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {   // 这里的initAnnotationType 就是子类set进去的@PostConstruct   // destroyAnnotationType 就是子类set进去的@PreDestroy   if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {     return this.emptyLifecycleMetadata;   }   // 存放初始化方法   List initMethods = new ArrayList<>();   // 存放销毁方法   List destroyMethods = new ArrayList<>();   Class<?> targetClass = clazz;    do {     final List currInitMethods = new ArrayList<>();     final List currDestroyMethods = new ArrayList<>();      ReflectionUtils.doWithLocalMethods(targetClass, method -> {       // 如果找到方法上有@PostConstruct注解,这加入到当前初始化方法集合中       if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {         // 创建一个生命周期元素         //LifecycleElement element = new LifecycleElement(method);         currInitMethods.add(new LifecycleElement(method));       }       // 如果找到方法上标有@PreDestroy 注解,就加入到当前销毁方法集合中       if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {         currDestroyMethods.add(new LifecycleElement(method));       }     });     // 赋值到初始化方法集合和销毁方法集合中     initMethods.addAll(0, currInitMethods);     destroyMethods.addAll(currDestroyMethods);     targetClass = targetClass.getSuperclass();   }   // 遍历查找   while (targetClass != null && targetClass != Object.class);   // 如果没有解析到,那么返回一个空的生命周期元数据,否则创建一个生命周期元素并放入初始化方法和销毁方法的集合   return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :           new LifecycleMetadata(clazz, initMethods, destroyMethods)); }
  最终发现实际上就是在解析我们的Bean的方法上是否标记了@PostConstruct注解和@PreDestroy方法,如果有就加入到生命周期元数据中,并且将解析到的方法放入到BeanDefinition的externallyManagedInitMethods和externallyManagedDestroyMethods集合中。
  Bean初始化和销毁方法解析和执行流程如下:
  Bean的合并大概的意思就是做了自定义初始化和销毁方法的解析,并在后期调用BPP时执行。
  Spring Bean的实例化基本就解析完了,接下来开始解析循环依赖和Bean的属性填充部分。
  如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,,咱们下期见。
  收藏 等于白嫖,点赞才是真情。
  原文 https://www.cnblogs.com/redwinter/p/16268667.html
房地产推广有哪些渠道?1软文推广软文推广,即是把房地产的相关内容负责撰写的,让用户通过软文可以清晰得了解到关于房地产的相关信息,加深他们对此房地产的理解,从而吸引用户消费。2视频营销推广短视频推广是目前你们都在回避一个问题,滴滴合法吗?我在一家规模较小的网约车公司做过运营人员,我来告诉你类似滴滴的网约车公司到底合不合法。首先,注册一家网约车公司在最近几年并不难拿到合法手续。第一步是你需要开发一套类似滴滴打车那样的什么是SEO优化?通过了解各类搜索引擎抓取互联网页面进行索引以及确定其对特定关键词搜索结果排名等技术,来对网页进行相关的优化,使其提高搜索引擎排名,从而提高网站访问量,最终提升网站的销售或宣传的效果ERP真的快要消失了吗?ERP不会消失,一定会升级用鱼骨图来描述下ERP,一个主箭头,开头是数据,结尾是利润。各部门都是主线上的点,这些点是公司各部门的职能,但有一点很重要协作!现在许多公司ERP失败主要小米10,想买个蓝牙耳机,最好是半入耳,有什么推荐?小米的手机就可以考虑小米耳机,毕竟适配会好点,或者京东上搜一下。如果对音质要求不高的话,我推荐QCY可以考虑一下,我个人买的是T1,平常上下班听歌听书感觉足够。这个品牌好像也是小米零售的本质重新解构人货场新零售这个概念最早被大家熟知,是2016年的阿里巴巴云栖大会上,马云提到未来的10年20年没有电子商务这一说,只有新零售,也就是说,线上线下和物流必须结合在一起,才能诞生真正的新零iPhone降价越来越凶,国产安卓却越卖越贵,这到底为何?今年iPhone13销量惊人,其中最主要的一个原因就是降价了,加量不加价能不香吗?反观国产安卓手机,这两年的售价是不断创新高,很多机型都已经比同年的iPhone贵了。这到底是为何?唠叨一下腾讯为什么让人反感腾讯作为一家由IM软件发展起来的巨头,可以说比较低调。与同为巨头的阿里相比,创始人几乎没什么发声,团队也相对更务实一些。按理说这种类型的公司应该更受欢迎,事实恰好相反,随便翻一篇关人类失去联想,世界将会怎样联想的专利是诺基亚买完摩托罗拉剩下的没用的专利,要这些个专利有啥用,能当5G专利收钱吗?能给国家撑腰吗?联想有毛超巨型机呀哪款,天河吗?好意思说出来,世界前十?世界不少国家气象部门三个喜讯传来!拒绝华为的台积电计划泡汤,中芯国际即将崛起台积电作为我国的企业却想跟着老美混,在失去利润的时候,又想回来赚中国人的钱,简直是可笑至极!国人各个都是小机灵鬼儿,又怎能允许你瞎搞呢?台积电在今年四月份的时候,董事会一致决定要花苹果安卓之争1苹果的优点系统流畅广告少广告少广告少重要的事情说三遍!!!相机白天拍照不错基本上能全部还原眼睛看到的色彩。晚上不行晚上不行晚上不行鬼影鬼影鬼影2苹果缺点续航不行快充不行信号不怎么
中国工程院院士徐建国新冠病毒是自然原性,不可能是人工制造中新网北京8月13日电(记者黄钰钦)中国工程院院士医学微生物学家徐建国13日在新冠病毒溯源问题驻华使节吹风会上表示,新冠病毒是自然原性,不可能是人工制造。他介绍称,从生物安全角度,轻薄快充我都要!这款充电头带起苹果全家桶,体积只有饼干那么大现在年轻人身边的数码设备越来越多,像许多果粉,他们除了最常用的iPhone手机以外,还往往有iPad平板和Macbook等多个设备来应对不同场合的需求,然而设备多不是什么问题,但是助听器与电视连接技术世界电视日电视和助听器技术发展日新月异11月21日是世界电视日自从第一届世界电视论坛于1996年11月21日在联合国召开后,1996年12月17日联合国大会宣布将这一天定为世界电视苹果M2芯片将于2022年上市,采用4nm工艺制造2020年11月11日,苹果隆重推出AppleM1芯片,由台积电使用其5nm工艺节点制造,使用ARM的架构,拥有高达160亿个晶体管,而A14仿生芯片组内部只有118亿个晶体管。A2021买手机追求性能拍照和气质,没理由不选这3款手机每一款手机都有自己主打的方向和定位,而对于那些追求性能拍照和气质的消费者来说,今年没有理由不选这3款手机,尽管它们价格都不低,但绝对值得一看。华为P50Pro尽管麒麟9000性能不RealmeX系列智能机已经谢幕RealmeGT系列将取而代之如果您出于某种原因而喜欢上了Realme的X系列智能机,那这里有个坏消息。该公司欧洲与印度首席执行官MadhavSheth刚刚在接受TechRadar采访时透露,后续将不再提供X系每日科普你的watch是怎么测心率的?不少业内人士都认为未来可穿戴智能手表手环需要向着更加专业化和细分化的应用领域发展,其中针对运动人群和健康检测就是两个很好的方向。那么我们不妨通过AppleWatch来了解一下光学心微软云PC漏洞可被明文转储MicrosoftAzure凭据一位安全研究人员,刚刚找到了一种利用Mimikatz,从微软Windows365CloudPC服务中转储用户未加密的明文MicrosoftAzure凭据的方法。据悉,Mimikat关于投资自动驾驶的一丁点前瞻思考毫无疑问,自动驾驶是汽车的下一个发展趋势。但目前在技术方向上还有不少分歧,以特斯拉为代表的厂商更注重视觉算法,而小鹏蔚来等厂商则倾向于提升激光雷达等硬件感知。两者方案各有优劣,既然骨传导屏幕发声等,曾经很火的黑科技,为何突然销声匿迹了?如果说黑科技,这些年可以说层出不穷,不过有许多被发扬光大了,但有些却逐渐淡出人们视野了,下面就来聊聊前几年很火,现在却没什么关注度的黑科技,这些黑科技为什么会销声匿迹了?骨传导耳机仅1899元,6nm芯片66W快充128GB,荣耀新款5G手机定价亲民了解行情的都知道,荣耀独立运营之后,上半年虽然也推出了不少产品,但是由于独立的时间相对短暂,推出的产品似乎给人一种匆匆忙忙上架的感觉,对比市面上的竞品,多多少少有些竞争力不足,比如