SpringBean生命周期

SpringBean的创建过程的生命周期可以简单分为

  • 通过构造方法创建普通对象
  • 对普通对象属性进行依赖注入(被@Autowired注解修饰的变量)
  • 执行初始化前的操作(被@PostConstruct注解修饰的方法)
  • spring提供的钩子函数BeanPostProcessor的postProcessBeforeInitialization()方法
  • 执行初始化操作(需要实现InitializingBean接口,重写afterPropertiesSet()方法)
  • spring提供的钩子函数BeanPostProcessor的postProcessAfterInitialization()方法
  • 初始化后操作(AOP切面生成代理对象)
  • 将代理对象或者普通对象(有aop操作则放入代理对象,否则放入普通对象)放入单例池中(Map)

Bean的创建流程图

加上awre相关操作后的Bean生命周期

  1. 实例化: new xxx();两个时机:1、当客户端向容器申请一个Bean时,2、当容器在初始化一个Bean时发现还需要依赖另一个Bean。BeanDefinition对象保存。
    1. -到底是new一个对象还是创建一个动态代理(如果有aop的情况需要动态代理)?
      1. 根据该Bean是否需要aop相关操作决定是否要创建动态代理
        1. 在AbstractAutoProxyCreator这个实现了BeanPostProcessor的spring aop自定义处理器中,在postProcessAfterInitialization这个后置处理器中会调用wrapIfNecessary(bean, beanName, cacheKey)这个方法,这个方法会执行aop相关的逻辑,查看该Bean是否aop切入,是否需要创建动态代理
  2. 设置对象属性(依赖注入): Spring通过BeanDefinition找到对象依赖的其他对象,并将这些对象赋予当前对象。
  3. 处理Aware接口: Spring会检测对象是否实现了xxAware接口,如果实现了,就会调用对应的方法。
  4. BeanNameAware、BeanClassLoaderAware、BeanFactoryAware、ApplicationContextAware
  5. BeanPostProcessor前置处理:调用BeanPostProcessor的postProcessBeforelnitialization方法
  6. InitializingBean: Spring检测对象如果实现了这个接口,就会执行他的afterPropertiesSet()方法,定制初始化逻辑。
  7. init-method: <bean init-method=xXx>如果Spring发现Bean配置了这个属性,就会调用他的配置方法,执行初始化逻辑。@PostConstruct
  8. BeanPostProcessor后置处理:调用BeanPostProcessor的postProcessAfterlnitialization方法到这里,这个Bean的创建过程就完成了,Bean就可以正常使用了。
  9. DisposableBean:当Bean实现了这个接口,在对象销毁前就会调用destory()方法。
  10. destroy-method: <bean destroy-method=xxx>@PreDestroy

创建流程都在

AbstractAutowireCapableBeanFactory的doCreateBean()方法中

最终Bean就被创建完成可以被使用了

通过构造方法创建普通对象

spring创建普通对象的规则是

  1. 当只有一个构造方法时使用该构造方法创建普通对象(没有构造器时默认使用无参构造方法来创建普通对象)
  2. 如果类中有多个构造方法,spring默认优先使用无参构造来创建普通对象,如果没有无参构造且构造方法有多个时使用被@Autowired注解修饰的构造方法来创建普通对象,如果没有被@Autowired注解修饰的构造方法则报错。

代理对象与普通对象的关系

spring在生成代理对象后并没有再次进行依赖注入等操作,那么代理对象是如何调用的注入的属性的呢?

答案是spring在生成代理对象后又依赖了原先进行了依赖注入等操作的普通对象,在进行完切面操作后再调用普通对象的方法,这样就能使用注入的属性了,基本代码为

class UserServiceProxy extends UserService {
    UserService target;

    public void test(){
        // @Before切面逻辑
        target.test();
    }
}

也就是说如果一个类有aop切面相关的操作的话,那么单例池(Map)中存放的是aop代理后的代理对象,代理对象持有进行了依赖注入后的普通对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值