spring学习笔记(spring注解驱动开发之bean的生命周期)

bean的生命周期

通常意义上讲的bean的生命周期,指的是bean从创建到初始化,经过一系列的流程,最终销毁的过程。只不过,在Spring中,bean的生命周期是由Spring容器来管理的。在Spring中,我们可以自己来指定bean的初始化和销毁的方法。我们指定了bean的初始化和销毁方法之后,当容器在bean进行到当前生命周期的阶段时,会自动调用我们自定义的初始化和销毁方法。

容器管理bean的生命周期的方法:

  1. @bean 指定初始化和销毁方法
  2. 通过让bean实现InitializingBean接口(定义初始化逻辑)和DisposableBean接口(定义销毁逻辑)
  3. 使用JSR250:@PostConstruct和@PreDestroy
  4. BeanPostProcessor:bean的后置处理器(重点)
一、@bean 指定初始化和销毁方法

在spring文件中配置bean的时候,是可以配置bean的初始化和销毁方法的。

    <bean id="car" class="com.wjh.bean.Car" init-method="init" destroy-method="destory">
    </bean>

在注解开发中在@bean注解的属性可以配置初始化和销毁的方法。
定义一个简单的car类。在类中定义初始化和销毁方法。

public class Car {

    public void init(){
        System.out.println("car...init()...了");
    }

    public void destory(){
        System.out.println("car...destory()...了");
    }
}

在配置类中配置bean,并且指定bean的初始化和销毁方法。

/**
 * bean的生命周期
 */
@Configuration
public class MainConfigOfLifeCycle {

    @Scope("singleton")
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Car car(){
        System.out.println("car实例注入容器中。。。");
        return new Car();
    }

}

测试:

@Test
    public void test7() {
        ApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
        System.out.println("容器初始化完成。。");
    }

测试结果:

car实例注入容器中。。。
car...init()...了
容器初始化完成。。

在单实例的情况下,容器在注入容器中的时候就执行了初始化方法了。至于销毁方法没有执行,是因为容器没有进行销,需要手动执行销毁方法。

  @Test
    public void test7() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
        System.out.println("容器初始化完成。。");
        context.close();
    }

说明:因为在ApplicationContext中没有close()方法,所以需要定义为实现了ApplicationContext 接口的AnnotationConfigApplicationContext类。
结果:

car实例注入容器中。。。
car...init()...了
容器初始化完成。。
car...destory()...了

在多实例的情况下,bean会等到被调用时才会注入容器。

@Configuration
public class MainConfigOfLifeCycle {

    @Scope("prototype")
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Car car(){
        System.out.println("car实例注入容器中。。。");
        return new Car();
    }

}

测试:

  @Test
    public void test7() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
        System.out.println("容器初始化完成。。");
        Object car = context.getBean("car");
        System.out.println(car);
        context.close();
    }
容器初始化完成。。
car实例注入容器中。。。
car...init()...了
com.wjh.bean.Car@4445629

在多实例的情况下,容器不会管理bean实例,所以没有执行销毁方法。

二、InitializingBean接口和DisposableBean接口

InitializingBean和DisposableBean的接口定义了

//实例创建之后执行
void afterPropertiesSet() throws Exception;
//容器销毁之后执行
void destroy() throws Exception;
@Component
public class Car implements InitializingBean, DisposableBean {

    public Car() {
        System.out.println("car被实例化了。。。");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("car执行了destroy()方法。。。");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("car执行了afterPropertiesSet()方法。。。");
    }

}
/**
 * bean的生命周期
 */
@Configuration
@ComponentScan("com.wjh")
public class MainConfigOfLifeCycle {

}

测试结果:

car被实例化了。。。
car执行了afterPropertiesSet()方法。。。
容器初始化完成。。
com.wjh.bean.Car@479d31f3
car执行了destroy()方法。。。
三、@PostConstruct和@PreDestroy

@PostConstruct:

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}

@PreDestroy:

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}

@PostConstruct和@PreDestroy注解都是可以标注在方法上的,作用:

  1. @PostConstruct:在bean创建完成并属性赋值完成,来执行初始化方法
  2. @PreDestroy:在容器销毁bean之前通知我们进行清理工作。

@Component
public class Dog {
    public Dog() {
        System.out.println("dog...constructor...");
    }

    @PostConstruct
    public void init() {
        System.out.println("car...@PostConstruct...init()...了");
    }

    @PreDestroy
    public void destory() {
        System.out.println("car...@PreDestroy...destory()...了");
    }
}

测试结果:

dog...constructor...
car...@PostConstruct...init()...了
容器初始化完成。。
com.wjh.bean.Dog@43195e57
car...@PreDestroy...destory()...了
四、BeanPostProcessor(重点)

在bean初始化前后进行一些出来工作。在spring和springboot中重点使用。

BeanPostProcessor接口:


	//在初始化之前工作
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	//在初始化之后工作
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

创建一个类,并实现BeanPostProcessor接口。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization..."+beanName+"----->"+beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization..."+beanName+"----->"+beanName);
        return bean;
    }
}

说明:需要注入到容器中
测试结果:

postProcessBeforeInitialization...mainConfigOfLifeCycle----->mainConfigOfLifeCycle
postProcessAfterInitialization...mainConfigOfLifeCycle----->mainConfigOfLifeCycle
dog...constructor...
postProcessBeforeInitialization...dog----->dog
car...@PostConstruct...init()...了
postProcessAfterInitialization...dog----->dog

说明:在bean的初始化前后工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值