spring 注解学习 二spring bean的生命周期

1、Spring中bean的初始化与销毁方法

spring的bean的生命周期大致可以分为以下部分:

1、对象的创建:单实例的Bean在容器初始化时创建,多实例Bean在每次获取的时候

2、属性的填充 populateBean

3、Aware接口的调用

4、BeanPostProcessor接口的postProcessBeforeInitialization调用

5、生命周期初始化方法:对象创建完成,并填充完属性之后

6、BeanPostProcessor接口的postProcessAfterInitialization调用

7、使用bean

8、生命周期销毁方法:单实例Bean在容器关闭时执行销毁方法,多实例的Bean是不放入容器中的,因此容器无法管理

在XML文件中的bean标签中可以配置生命周期初始化方法与生命周期销毁方法

 <bean id="person" class="com.caopeng.bean.Person" destroy-method="init" init-method="destory"></bean>

那么在注解版本中,也可以通过@Bean注解中的一些属性来配置

1.1、类的定义

public class Car {

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

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

    public void destory(){
        System.out.println("destory 方法");
    }
}

1.2、java配置文件中注入Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfigOfLifeCycle {
	//通过initMethod与destroyMethod方法来指定初始化与销毁方法
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Car car(){
        return  new Car();
    }
}

1.3、测试

public class DemoLifeCycle {

    @Test
    public void fun01(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(AppConfigOfLifeCycle.class);
        Object car = applicationContext.getBean("car");
       // 关闭容器
        applicationContext.close();

    }
}

1.4、运行结果

constructor
init 方法
destory 方法

如果把Car变成多实例Bean

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

这样在容器关闭时就不会调用destory方法

2、通过实现InitializingBean接口与DisposableBean接口

2.1、InitializingBean

package org.springframework.beans.factory;


public interface InitializingBean {

	void afterPropertiesSet() throws Exception;

}

2.2、DisposableBean

package org.springframework.beans.factory;


public interface DisposableBean {


	void destroy() throws Exception;

}

2.3、示例

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

@Component
public class Cat implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }

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

3、JSR250中的@PostConstruct与@PreDestroy注解

@Component
public class Dog {

    @PostConstruct
    public void init(){
        System.out.println("dog:init");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("dog:destroy");
    }
}

4、BeanPostProcessor接口

在bean填充完属性之后,还有一个方式可以初始化bean与销毁bean,就是定义一个实现BeanPostProcessor类。

4.1、BeanPostProcessor接口说明

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

/**
 允许自定义修改新bean实例的工厂回调方法,例如,检查标记接口或用代理包装bean。

 ApplicationContext可以在其bean定义中自动检测出哪些是BeanPostProcessor类型的bean,并将这些后处理器应用于随后创建的任何bean。普通BeanFactory允许对后置处理器进行注册,将后置处理器应用于通过BeanFactory创建的所有bean。
*/
public interface BeanPostProcessor {
/*
1、在新的Bean实例的任何的初始化回调方法(例如:InitializingBean接口的afterPropertiesSet方法 或者自定义的init-method)调用之前,调用postProcessBeforeInitialization方法。
2、返回的实例可以是原来的对象 ,也可以是被包裹后的对象
3、默认实现按原样返回给定bean。
@param bean the new bean instance
@param beanName the name of the bean
@return the bean instance to use, either the original or a wrapped one;
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
1、在初始化方法调用之后调用postProcessAfterInitialization,在InitializingBean接口的afterPropertiesSet方法 或者自定义的init-method调用之后工作
2、返回的实例可以是原来的对象 ,也可以是被包裹后的对象
3、默认实现按原样返回给定bean。
 @param bean the new bean instance
 @param beanName the name of the bean
 @return the bean instance to use, either the original or a wrapped one;
	
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

4.2、实例

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

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

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

4.3、运行结果

appConfigOfLifeCycle>>>BeanPostProcessor::postProcessBeforeInitialization
appConfigOfLifeCycle>>>BeanPostProcessor::postProcessAfterInitialization
cat>>>BeanPostProcessor::postProcessBeforeInitialization
Cat>>InitializingBean::afterPropertiesSet
cat>>>BeanPostProcessor::postProcessAfterInitialization
dog>>>BeanPostProcessor::postProcessBeforeInitialization
dog:init
dog>>>BeanPostProcessor::postProcessAfterInitialization
Car::constructor
car>>>BeanPostProcessor::postProcessBeforeInitialization
Car::init 方法
car>>>BeanPostProcessor::postProcessAfterInitialization
Car::destory 方法
dog:destroy
Cat>>>DisposableBean::destroy

BeanPostProcessor接口中的方法在spring中用户定义的所有bean都会起作用,而之前的三种配置方式只是针对特定的bean起作用

5、初始化方法的调用顺序原理

AbstractAutowireCapableBeanFactory类的createBean ->doCreateBean->populateBean以及initializeBean

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
            //调用Aware接口
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            //调用接口的前置方法postProcessBeforeInitialization
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            //调用生命周期的初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
             //调用接口的后置方法postProcessAfterInitialization
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
原文地址:https://www.cnblogs.com/cplinux/p/14530462.html