08-Bean的生命周期

目录

1、@Bean指定初始化和销毁方法

2、通过让Bean实现 InitializingBean接口(定义初始化逻辑),实现 DisposableBean(定义销毁逻辑)

编写测试代码

3、可以使用JSR250;

         @PostConstruct:在bean创建完成并且属性赋值完成;在执行初始化方法。

         @PreDestroy:在容器销毁bean之前通知我们进行清理工作。

4、BeanPostProcessor【interface】:bean后置处理器,在bean初始化前后进行一些处理工作。

      -postProcessBeforeInitialization:在初始化之前工作。

      -postProcessAfterInitialization:在初始化之后工作。


1、@Bean指定初始化和销毁方法

以前通过xml配置文件方式,初始化和销毁Bean组件,是通过 init-method 和 destroy-method 调用指定的方法

<bean id="person" name="person" class="com.spring.bean.Person" init-method="" destroy-method="">
        <property name="age" value="18"></property>
        <property name="name" value="zhang"></property>
    </bean>

注解方式如何实现呢?

首先先创建Car类,并添加init() 和destory()方法

package com.spring.bean;

public class Car {

    public Car(){
        System.out.println("Car constructor...");
    }

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

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

然后创建Spring配置类,并添加创建Bean Car的方法

/**
 * Bean 的生命周期
 *      Bean创建-->初始化-->销毁过程
 * 容器管理bean的生命周期
 * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期时,调用自定义初始化、销毁方法。
 *
 * 构造
 *    单实例:在容器启动的时候创建对象
 *    多实例:在每次获取的时候创建对象
 *
 * 初始化:
 *    对象创建完成,并赋值好,调用初始化方法...
 * 销毁:
 *    单实例:在容器关闭的时候销毁。
 *    多实例:容器不会管理这个bean,容器不会调用销毁方法。
 *
 * 1)、指定初始化和销毁方法
 *      通过@Bean指定initMethod 和 destroyMethod
 *
 */

@Configuration
public class MainConfigOfLiftCycle {

    @Scope("prototype")
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Car car(){
        return new Car();
    }
}

执行测试方法

public class IocTest_BeanLifeCycle {

    @Test
    public void test01(){
        //1、创建ioc容器
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfigOfLiftCycle.class);
        System.out.println("容器创建完成...");


        annotationConfigApplicationContext.close();
    }

输出结果为:

三月 29, 2020 9:21:10 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@587d1d39: startup date [Sun Mar 29 09:21:10 CST 2020]; root of context hierarchy
Car constructor...
car...init...
容器创建完成...
三月 29, 2020 9:21:11 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@587d1d39: startup date [Sun Mar 29 09:21:10 CST 2020]; root of context hierarchy
car...distory...

以上是在单实例测试结果,在容器关闭的时候,调用销毁方法。

多实例情况如何?,添加@Scope("prototype")

 @Scope("prototype")
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Car car(){
        return new Car();
    }

修改测试方法,多实例是在每次获取的时候向容器中注册Bean组件

 @Test
    public void test01(){
        //1、创建ioc容器
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfigOfLiftCycle.class);
        System.out.println("容器创建完成...");


        Object car = annotationConfigApplicationContext.getBean("car");
        annotationConfigApplicationContext.close();
    }

测试结果:

容器创建完成...
Car constructor...
car...init...

可以看出,没有调用销毁方法。


*******************************************************************************************

* 构造:
*    单实例:在容器启动的时候创建对象
*    多实例:在每次获取的时候创建对象
*
* 初始化:
*    对象创建完成,并赋值好,调用初始化方法...
*
* 销毁:
*    单实例:在容器关闭的时候销毁。
*    多实例:容器不会管理这个bean,容器不会调用销毁方法*******************************************************************************************


2、通过让Bean实现 InitializingBean接口(定义初始化逻辑),实现 DisposableBean(定义销毁逻辑)

创建Cat类,并实现InitializingBean、DisposableBean

package com.spring.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class Cat implements InitializingBean, DisposableBean {

    public Cat(){
        System.out.println("cat constructor...");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("cat...afterPropertiesSet...");
    }

    public void destroy() throws Exception {
        System.out.println("cat...destroy...");
    }
}

配置类代码,通过@ComponentScan("com.spring.bean") 包扫描方式,注册组件

@ComponentScan("com.spring.bean")
@Configuration
public class MainConfigOfLiftCycle {

}

编写测试代码

 @Test
 public void test02(){
        //1、创建ioc容器
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfigOfLiftCycle.class);
        System.out.println("容器创建完成...");
        annotationConfigApplicationContext.close();
    }

输出结果为

cat constructor...
cat...afterPropertiesSet...
容器创建完成...
三月 29, 2020 1:13:36 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@587d1d39: startup date [Sun Mar 29 13:13:35 CST 2020]; root of context hierarchy
cat...destroy...

3、可以使用JSR250;

         @PostConstruct:在bean创建完成并且属性赋值完成;在执行初始化方法。

         @PreDestroy:在容器销毁bean之前通知我们进行清理工作。

 

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

    //在对象创建并赋值之后调用
    @PostConstruct
    public void init(){
        System.out.println("Dog...PostConstruct...");
    }

    //在容器移除对象之前
    @PreDestroy
    public void destroy(){
        System.out.println("Dog...PreDestroy...");
    }
}

测试输出结果

信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@587d1d39: startup date [Sun Mar 29 13:24:39 CST 2020]; root of context hierarchy
Dog constructor...
Dog...PostConstruct...
容器创建完成...
三月 29, 2020 1:24:39 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@587d1d39: startup date [Sun Mar 29 13:24:39 CST 2020]; root of context hierarchy
Dog...PreDestroy...

更改Dog类作用域为多例

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

    //在对象创建并赋值之后调用
    @PostConstruct
    public void init(){
        System.out.println("Dog...PostConstruct...");
    }

    //在容器移除对象之前
    @PreDestroy
    public void destroy(){
        System.out.println("Dog...PreDestroy...");
    }
}

输出结果为:

容器创建完成...
Dog constructor...
Dog...PostConstruct...
Dog constructor...
Dog...PostConstruct...

4、BeanPostProcessor【interface】:bean后置处理器,在bean初始化前后进行一些处理工作。

      -postProcessBeforeInitialization:在初始化之前工作。

      -postProcessAfterInitialization:在初始化之后工作。

@Component
public class MyBeanPostPrecessor implements BeanPostProcessor {

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

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

执行上线的测试代码,测试结果为

postProcessBeforeInitialization...org.springframework.context.event.internalEventListenerProcessor bean-->org.springframework.context.event.EventListenerMethodProcessor@3012646b
postProcessAfterInitialization...org.springframework.context.event.internalEventListenerProcessor bean-->org.springframework.context.event.EventListenerMethodProcessor@3012646b
postProcessBeforeInitialization...org.springframework.context.event.internalEventListenerFactory bean-->org.springframework.context.event.DefaultEventListenerFactory@4a883b15
postProcessAfterInitialization...org.springframework.context.event.internalEventListenerFactory bean-->org.springframework.context.event.DefaultEventListenerFactory@4a883b15
postProcessBeforeInitialization...mainConfigOfLiftCycle bean-->com.spring.Condition.MainConfigOfLiftCycle$$EnhancerBySpringCGLIB$$4cc8cd56@5824a83d
postProcessAfterInitialization...mainConfigOfLiftCycle bean-->com.spring.Condition.MainConfigOfLiftCycle$$EnhancerBySpringCGLIB$$4cc8cd56@5824a83d
Dog constructor...
postProcessBeforeInitialization...dog bean-->com.spring.bean.Dog@4686afc2
Dog...PostConstruct...
postProcessAfterInitialization...dog bean-->com.spring.bean.Dog@4686afc2
容器创建完成...
Dog...PreDestroy...

每个Bean组件都会在初始化之前调用postProcessBeforeInitialization 方法,在初始化之后调用postProcessAfterInitialization 方法。

结合Dog类

可以看出调用顺序

Dog constructor...  //构造
postProcessBeforeInitialization...dog bean-->com.spring.bean.Dog@4686afc2
Dog...PostConstruct...  
postProcessAfterInitialization...dog bean-->com.spring.bean.Dog@4686afc2
容器创建完成...
Dog...PreDestroy...


BeanPostProcessor原理

populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值

initializeBean(beanName, exposedObject, mbd);{
    applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

    invokeInitMethods(beanName, wrappedBean, mbd);

   applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

}


 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值