【spring注解开发】2、Bean的生命周期(创建、初始化及销毁的过程)

【spring注解开发】1、快速体验IOC,给容器中注册组件 这一小节,我们已经把Bean的生命周期交由容器管理,我们可以自定义初始化和销毁的方法,当容器管理Bean进行到相应的生命周期的时候就会调用相应的方法。

1、两种指定初始化和销毁方法的方式

1.1、 @Bean指定的方式

在User类中创建init和destroy方法,

package com.xx.ioc.model;

public class User {

    public User() {
        System.out.println("---> user.constructor");
    }
    public void init() {
        System.out.println("---> user.init");
    }

    public void destroy() {
        System.out.println("---> user.destroy");
    }
}

接下来我们使用@Bean的方式注册组件,

@Configuration  // 这是一个配置类
public class UserConfig {
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public User user() {
        return new User();
    }
}

现在在main方法中来创建以及关闭容器,观察可以看到,容器创建的时候会执行构造器以及指定的init方法,关闭容器之前会执行destroy方法。

public class Main {
    public static void main(String[] args) {
//        User user = new User();
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(UserConfig.class);
        System.out.println("容器创建完成");
        ctx.close();
        System.out.println("容器已关闭");
    }
}
/*打印:
---> user.constructor
---> user.init
容器创建完成
---> user.destroy
容器已关闭
 */

1.2、 实现InitializingBean和DisposableBean接口的方式

在InitializingBean源码可以看到,在设置完成Bean之后会调用afterPropertiesSet方法。

public interface InitializingBean {

	/**
	 * Invoked by the containing {@code BeanFactory} after it has set all bean properties
	 * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
	 * <p>This method allows the bean instance to perform validation of its overall
	 * configuration and final initialization when all bean properties have been set.
	 * @throws Exception in the event of misconfiguration (such as failure to set an
	 * essential property) or if initialization fails for any other reason
	 */
	void afterPropertiesSet() throws Exception;

}

DisposableBean接口中的destroy方法会在销毁Bean时调用。

public interface DisposableBean {

	/**
	 * Invoked by the containing {@code BeanFactory} on destruction of a bean.
	 * @throws Exception in case of shutdown errors. Exceptions will get logged
	 * but not rethrown to allow other beans to release their resources as well.
	 */
	void destroy() throws Exception;

}

下面我们就让User类实现这两个接口,并实现其中的方法,

public class User implements InitializingBean, DisposableBean {

    public User() {
        System.out.println("---> user.constructor");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("---> user.destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("--> user.afterPropertiesSet");
    }
}

在配置类中注册User,

@Configuration  // 这是一个配置类
public class UserConfig {
    @Bean
    public User user() {
        return new User();
    }
}

接下来,就可以在main方法中获取这个user对象,观察输出可以看到容器创建的时候会实例化User对象,关闭容器的时候会先销毁User对象。

public class Main {
    public static void main(String[] args) {
//        User user = new User();
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(UserConfig.class);
        System.out.println("容器创建完成");
        ctx.close();
        System.out.println("容器已关闭");
    }
}
/*
---> user.constructor
--> user.afterPropertiesSet
容器创建完成
---> user.destroy
容器已关闭
*/

2、BeanPostProcessor后置处理器

BeanPostProcessor,在bean初始化前后进行一些处理工作。BeanPostProcessor接口中有两个方法,

public interface 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;
	}

}
  • postProcessBeforeInitialization 初始化之前进行一些后置工作
  • postProcessAfterInitialization 初始化之后进行后置工作

接上面的例子,我们就创建MyBeanPostProcessor实现BeanPostProcessor接口,并实现其中的方法,并用@Component注册到容器中去,

package com.xx.ioc.config;

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

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

让我们的UserConfig类可以扫描到MyBeanPostProcessor,

package com.xx.ioc.config;
import com.xx.ioc.model.User;

@Configuration  // 这是一个配置类
@ComponentScan("com.xx.ioc.config")
public class UserConfig {
    @Bean
    public User user() {
        return new User();
    }
}

最后,在main方法中我们获取user实列,我们可以观察到在设置user前后分别执行了postProcessBeforeInitialization和postProcessAfterInitialization方法,

public class Main {
    public static void main(String[] args) {
//        User user = new User();
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(UserConfig.class);
        System.out.println("容器创建完成");
        ctx.close();
        System.out.println("容器已关闭");
    }
}
/*打印:
--->postProcessBeforeInitialization,--->bean com.xx.ioc.config.UserConfig$$EnhancerBySpringCGLIB$$86643ebe@f0f2775,--->beanName userConfig
--->postProcessAfterInitialization,--->bean com.xx.ioc.config.UserConfig$$EnhancerBySpringCGLIB$$86643ebe@f0f2775,--->beanName userConfig
---> user.constructor
--->postProcessBeforeInitialization,--->bean com.xx.ioc.model.User@29ba4338,--->beanName user
--> user.afterPropertiesSet
--->postProcessAfterInitialization,--->bean com.xx.ioc.model.User@29ba4338,--->beanName user
容器创建完成
---> user.destroy
容器已关闭
 */

可以看到,MyBeanPostProcessor不仅作用在了User类上,只要是注册到容器中的组件都起了作用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值