spring注解-bean生命周期

https://www.jianshu.com/p/70b935f2b3fe

bean的生命周期

  bean创建---初始化----销毁的过程

容器管理bean的生命周期

  • 对象创建:容器启动后调用bean的无参构造函数创建bean
    • 单实例:在容器启动的时候创建对象
    • 多实例:在每次获取的时候创建对象
  • 初始化:对象创建完成后调用初始方法(BeanPostProcessor可以对bean初始化前后进行拦截处理)
  • 销毁:容器关闭
    • 单实例:容器关闭的时候进行销毁
    • 多实例:容器不会管理这个bean(不会自动调用销毁方法),需要我们自己手工调用相应方法进行销毁

 

自定义初始和销毁方法

通过@Bean指定init-method和destroy-method

  容器在bean进行到某个生命周期的时候来调用组件中我们自定义的任意方法(都可作为初始和销毁方法)

复制代码
//@Scope("prototype")
@Bean(initMethod="init",destroyMethod="detory")
public Car car(){
  return new Car();
}

//以往在xml定义初始和销毁方法
<bean id="person" class="com.bean.Person"  scope="prototype" init-method="" destroy-method=""></bean>
复制代码

通过让Bean实现InitializingBean、DisposableBean接口的方法

  用@Bean将组件注册到容器里;省略。。。

复制代码
public class Cat implements InitializingBean,DisposableBean {
    
    public Cat(){
        System.out.println("cat constructor...");
    }

    @Override
    public void destroy() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("cat...destroy...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("cat...afterPropertiesSet...");
    }
复制代码

使用JSR250

复制代码
    //在bean创建完成并且属性赋值完成后来执行初始化方法
@PostConstruct
public void init(){
System.out.println("Dog....@PostConstruct...");
}
//在容器销毁bean之前
   @PreDestroy
   public void detory(){
System.out.println("Dog....@PreDestroy...");
}
复制代码

 

实现BeanPostProcessor接口

  bean的后置处理器,在(所有)bean初始化前后进行一些处理工作;用@Bean将组件注册到容器里;省略。。。

    • postProcessBeforeInitialization:在初始化之前工作
    • postProcessAfterInitialization:在初始化之后工作
复制代码
  public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
        return bean;
    }

}
复制代码

 BeanPostProcessor原理

复制代码
populateBean(beanName, mbd, instanceWrapper);//给bean进行属性赋值
initializeBean
{
    applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
    applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
复制代码

 

Spring底层对 BeanPostProcessor 的使用

  查看所有实现了BeanPostProcessor接口的实现类,发现bean赋值、@Import(注入其他组件)、@Autowired、@PostConstruct(生命周期注解)、@Async都是通过大量的XXXBeanPostProcessor实现的。也就是说这些功能在bean创建完成后,beanPostProcessor在它们初始化前后进行了一系列处理工作,比如在某个bean中需要ioc容器的操作:

复制代码
//实现ApplicationContextAware接口,ioc容器会自动在dog创建完成后执行setApplicationContext进行赋值;
而之所以会这么做是因为有个ApplicationContextAwareProcessor,它会对所有实现了

ApplicationContextAware的bean进行赋值操作
public class Dog implements ApplicationContextAware


  @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // TODO Auto-generated method stub
        this.applicationContext = applicationContext;
    }
复制代码

 

 

 

 

posted @   edda_huang  阅读(405)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示

目录导航