Spring生命周期回调三种方式及源码分析


三种方式

  1. @Bean指定初始化和销毁方法
  2. 实现InitializingBean和DisposableBean
  3. @PostConstruct&@PreDestroy

先说执行顺序
初始化执行顺序3>2>1
销毁执行顺序3>2>1
源码下面会分析

代码示例

以下将三种方式一起使用,以便看出他们的执行顺序

/**
 * @desc 用来测试注入的时机与生命周期回调
 */
@Component
public class Role {
    public Role() {
        System.out.println("role===============");
    }
}
public class User implements InitializingBean, DisposableBean {

    @Autowired
    private Role role;

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

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

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

    @Override
    // 实现DisposableBean的方法
    public void destroy() throws Exception {
        System.out.println("user++destory");
    }

    @Override
    // 实现InitializingBean的方法
    public void afterPropertiesSet() throws Exception {
        System.out.println("user++init");
    }


    @PostConstruct
    public void postConstructor() {
        System.out.println("postConstructor");
    }

    @PreDestroy
    public void preDestory() {
        System.out.println("preDestory");
    }
}
@Configuration
@ComponentScan("com.demo.init")
public class Test {

    // Bean指定初始化和销毁方法
    @Bean(initMethod = "aaa",destroyMethod = "bbb")
//    @Scope("prototype")
    public User get(){
        return new User();
    }
}
// 启动类
public class Start {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Test.class);
        applicationContext.getBean(User.class);
        System.out.println("applicationContext will close");
        applicationContext.close();
    }
}

执行结果

改变bean的作用域

@Scope(“singleton”)–单例

role===============
user--constructor
@postConstructor
InitializingBean++init
bean  init   aaa
applicationContext will close
@preDestory
DisposableBean++destory
bean destory  bbb

@Scope(“prototype”)–原型

由于原型的bean只有在调用时才会初始化
如果没有applicationContext.getBean(User.class),user将不会初始化
不交给beanFactory来管理,所以也不会执行销毁方法

role===============
user--constructor
@postConstructor
InitializingBean++init
bean  init   aaa
applicationContext will close

源码分析

关键代码写在源码中的注释里

初始化方法

依次进入以下方法

  1. org.springframework.context.support.AbstractApplicationContext#refresh
  2. org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
  3. org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons
  4. org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
  5. org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
  6. org.springframework.beans.factory.support.AbstractBeanFactory#createBean
  7. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
  8. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
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 {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            // @PostConstruct是由CommonAnnotationBeanPostProcess实现的
            // 这个方法里将会遍历BeanPostProcessor去执行
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            // 1.2两种方式会在这个方法里执行,看下面源码
			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()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
                // 首先会执行这个方法
                // 即实现InitializingBean的afterPropertiesSet()方法
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
                
                // 这里会执行@Bean指定init方法
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

销毁方法

因为applicationContext.close()
最终会去执行如下方法
org.springframework.beans.factory.support.DisposableBeanAdapter#destroy

看注释

public void destroy() {
		if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
				// 这里会执行@PreDestroy
                processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}

		if (this.invokeDisposableBean) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
			}
			try {
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((DisposableBean) this.bean).destroy();
						return null;
					}, this.acc);
				}
				else {
                    // 这里会执行实现DisposableBean的destroy()方法
					((DisposableBean) this.bean).destroy();
				}
			}
			catch (Throwable ex) {
				String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
				if (logger.isDebugEnabled()) {
					logger.warn(msg, ex);
				}
				else {
					logger.warn(msg + ": " + ex);
				}
			}
		}

		if (this.destroyMethod != null) {
            // 这里会执行@Bean指定的销毁方法
			invokeCustomDestroyMethod(this.destroyMethod);
		}
		else if (this.destroyMethodName != null) {
			Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
			if (methodToInvoke != null) {
				invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
			}
		}
	}
发布了37 篇原创文章 · 获赞 1 · 访问量 1046

猜你喜欢

转载自blog.csdn.net/zhuchencn/article/details/104025890