springbean生命周期
2021-10-19 09:06:38 0 举报
springbean生命周期
作者其他创作
大纲/内容
分为填充属性和填充属性后。其实也就是实现类,然后可以对属性填充和填充后进行属性修改
最终扫描到某些BeanDefinition。beanClass属性存储的是当前类的名字,而不是class对象
通过扫描得到所有BeanDefinition之后,就可以根据BeanDefinition创建Bean对象了,但是在Spring中支持父子BeanDefinition,和Java父子类类似,但是完全不是一回事。因为child的父BeanDefinition是parent,所以会继承parent上所定义的scope属性。 而在根据child来生成Bean对象之前,需要进行BeanDefinition的合并,得到完整的child的BeanDefinition
扫描结束
生成BeanDefinition
实例化后
执行Aware
实例化前
利用初始化前,可以对进行了依赖注入的Bean进行处理。 在Spring源码中:1、InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法,2、ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:EnvironmentAware:回传环境变量EmbeddedValueResolverAware:回传占位符解析器ResourceLoaderAware:回传资源加载器ApplicationEventPublisherAware:回传事件发布器MessageSourceAware:回传国际化资源ApplicationStartupAware:回传应用其他监听对象,可忽略ApplicationContextAware:回传Spring容器ApplicationContext
扫描传入的路径。得到包路径下的所有class文件对象,注意不是Class对象,而是文件对象(可以理解为File对象)
查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法执行BeanDefinition中指定的初始化方法
spring 默认调用无参构造方法,没有无参的构造方法,会寻找有参的构造方法 ,如果有两个有参的构造方法,会去找无参的构造方法 故而会报一个找不到默认构造方法的异常。当然也可以指定Spring使用其中的一个,方法就是加上 @Autowired注解。如果只有一个有参的构造方法,那么找对应的参数,详细如下pubLic UserService(Orderservice orderService123){// Map<beanName,bean对象> this.orderService = orderService123; System.out.printLn(\"2\");}Orderservice 是类型,orderService123是名称 寻找的时候会先找类型,如果找到一个,那么直接引用,如果多个再根据名称找,找不到抛出异常
BeanDefinition的后置处理
如果不是顶级类,或者静态内部类,则不通过
当前BeanDefinition对应的类成功加载后,就可以实例化对象了。在实例化前这一步spring提供了一个扩展点。允许用户来控制是否在某个或某些Bean实例化之前做一些启动动作。这个扩展点叫InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
其实就是写个类可以实现下MergedBeanDefinitionPostProcessor,重写下postProcessMergedBeanDefinition方法。可以对BeanDefinition的属性进行修改
Supplier创建对象首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。 得直接使用BeanDefinition对象来设置Supplier
初始化
实例化
详细
这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessAfterInitialization()。可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象。
如果是抽象类,但是有@Lookup注解的方法,则通过
根据BeanDefinition去创建一个对象
遍历每个BeanDefinition
加载类
判断当前beanName是否在Spring容器中已经存在,如果不存在则把beanName以及BeanDefinition注册到Spring 容器中,如果存在则报错
完成了属性赋值之后,Spring会执行一些回调,包括:BeanNameAware:回传beanName给bean对象。BeanClassLoaderAware:回传classLoader给bean对象。BeanFactoryAware:回传beanFactory给对象
工厂方法创建对象如果没有设置Supplier,则检查BeanDefinition中是否设置了factoryMethod,也就是工厂方法
合并BeanDefinition
利用ASM技术(MetadataReader)解析每个class文件对象,得到class元数据信息,如果当前类和某个excludeFilter匹配,那就排除这个类。如果当前类和某个includeFilter匹配,那就通过这个类。
自定义一个类实现InstantiationAwareBeanPostProcessor 接口,可以在里面重写方法,对bean属性进行操作。如果直接返回一个实例化后的类,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步
都匹配成功后,根据当前类生成一个ScannedGenericBeanDefinition
初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization()
//如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)if (mbd.hasBeanClass()) { return mbd.getBeanClass();}if (System.getSecurityManager() != null) {font color=\"#9c27b0\
Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工
BeanDefinition合并之后,就可以去创建Bean对象了,而创建Bean就必须实例化对象,而实例化就必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的createBean()方法中
如果是抽象类或者接口,则不通过
初始化后
在Spring源码中,AutowiredAnnotationBeanPostProcessor就是一个MergedBeanDefinitionPostProcessor,它的postProcessMergedBeanDefinition()中会去查找注入点,并缓存在AutowiredAnnotationBeanPostProcessor对象的一个Map中(injectionMetadataCache)
推断构造方法
Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建Bean对象做准备。
初始化前
在处理完BeanDefinition后,Spring又设计了一个扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
处理属性
解析@Lazy、@Primary、@DependsOn、@Role、@Description等注解并赋值给BeanDefinition对应的属性
进一步进行条件注解@Conditional的匹配筛选。判断是否是独立的,是不是接口等等
Bean生命周期
推断构造方法在实例化时,如果判断出来当前BeanDefinition中没有LookupOverride,那就直接用构造方法反射得到一个实例对象。如果存在LookupOverride对象,也就是类中存在@Lookup注解了的方法,那就会生成一个代理对象
收藏
收藏
0 条评论
回复 删除
下一页