【Spring注解】2、Bean生命周期

版权声明:本文为博主原创文章,未经博主允许不得转载。请联系博主或者emailTo:[email protected],谢谢! https://blog.csdn.net/caychen/article/details/83009432

1、初始化和销毁

  • 通过@Bean注解的initMethoddestroyMethod属性

  • InitializingBean接口、DisposableBean接口

  • 可以使用JSR250:

    • @PostConstruct:在Bean创建完成并且属性值完成后,执行初始化。

    • @PreDestroy:在容器销毁Bean之前,通知进行清理工作。

  • 使用Spring的BeanPostProcessor接口

1.1、通过@Bean注解的initMethod和destroyMethod属性

//bean类
public class Car {

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

通过@Bean注解的initMethoddestroyMethod属性

/**
 * bean的生命周期:
 * 	bean创建---初始化---销毁的过程
 * 
 * 容器管理bean的生命周期
 * 我们可以自定义初始化和销毁方法:容器在bean进行到生命周期的时候来调用我们自定义的初始化和销毁方法
 * 
 * 构造:
 * 		单实例:在容器启动的时候创建对象
 * 		多实例:在每次获取的时候创建对象
 * 初始化:
 * 		对象创建完成后,调用初始化方法
 * 销毁:
 * 		单实例:容器关闭的时候
 * 		多实例:容器不会管理这个bean,所以容器不会调用销毁方法
 * 
 * 1)、指定初始化和销毁方法:
 * 		通过@Bean指定init-method和destroy-method
 * 
 * @author Cay
 * @date 2018年8月25日 下午5:18:43
 */
@Configuration
public class MyConfigOfLifeCycle {

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

测试:

public class TestLifeCycle {

	@Test
	public void test1(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
		System.out.println("容器创建完成...");
		
		applicationContext.close();
	}
}

单实例bean的初始化和销毁测试结果:

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


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

 多实例bean的初始化和销毁测试结果:

 对比两图可以看出,单实例bean和多实例bean在初始化和销毁时的不同。

1.2、InitializingBean接口、DisposableBean接口

通过让Bean实现InitializingBean接口实现初始化逻辑,实现DisposableBean接口实现销毁逻辑。

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 init...");
	}
}

1.3、@PostConstruct、@PreDestroy

  • @PostConstruct:在Bean创建完成并且属性值完成后,执行初始化。

  • @PreDestroy:在容器销毁Bean之前,通知进行清理工作。

public class Dog {

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

1.4、Spring的BeanPostProcessor接口

BeanPostProcessor是bean的后置处理器:

  • 在bean初始化前后进行一些处理工作:

  • postProcessBeforeInitialization:在初始化之前

  • postProcessAfterInitialization:在初始化之后

@Component
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原理:

  • AbstractAutowireCapableBeanFactory#configureBean
public Object configureBean(Object existingBean, String beanName) throws BeansException {
    markBeanAsCreated(beanName);
    BeanDefinition mbd = getMergedBeanDefinition(beanName);
    RootBeanDefinition bd = null;
    if (mbd instanceof RootBeanDefinition) {
        RootBeanDefinition rbd = (RootBeanDefinition) mbd;
        bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition());
    }
    if (!mbd.isPrototype()) {
        if (bd == null) {
            bd = new RootBeanDefinition(mbd);
        }
        bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
        bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
    }
    //生成bean的包装对象,并初始化包装类
    BeanWrapper bw = new BeanWrapperImpl(existingBean);
    initBeanWrapper(bw);
    //给bean进行赋值
    populateBean(beanName, bd, bw);
    //初始化bean
    return initializeBean(beanName, existingBean, bd);
}
  • AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    //other...

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

    try {
        //调用init方法
        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()) {
        //调用applyBeanPostProcessorsAfterInitialization方法
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}
  • AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        //调用每个BeanPostProcessor实现类的postProcessBeforeInitialization方法
        result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}
  • AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
		throws Throwable {

    //判断bean是否实现了InitializingBean接口
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                    @Override
                    public Object run() throws Exception {
                        //调用InitializingBean实现类的afterPropertiesSet方法
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            //调用InitializingBean实现类的afterPropertiesSet方法
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null) {
        String initMethodName = mbd.getInitMethodName();
        if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}
  • AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    //调用每个BeanPostProcessor实现类的postProcessAfterInitialization方法
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        result = beanProcessor.postProcessAfterInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

====================打个广告,欢迎关注====================

QQ:

412425870

微信公众号:Cay课堂

csdn博客:

http://blog.csdn.net/caychen

码云:

https://gitee.com/caychen/

github:

https://github.com/caychen

点击群号或者扫描二维码即可加入QQ群:

328243383(1群)

 

点击群号或者扫描二维码即可加入QQ群:
180479701(2群)

--------------------- 作者:caychen 来源:CSDN 原文:https://blog.csdn.net/caychen/article/details/83008897?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/caychen/article/details/83009432