When container starts – a Spring bean needs to be instantiated, based on Java or XML bean definition. It may also be required to perform some post-initialization steps to get it into a usable state. Same bean life cycle is for spring boot applications as well.
前言 Spring Bean的生命周期只有这四个阶段。把这四个阶段和每个阶段对应的扩展点糅合在一起虽然没有问题,但是这样非常凌乱,难以记忆。要彻底搞清楚Spring的生命周期,首先要把这四个阶段牢牢记住。实例化和属性赋值对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。在这四步之间穿插的各种扩展点。
Bean 四个阶段:
1).实例化 Instantiation 2).属性赋值 Populate 3).初始化 Initialization 4).销毁 Destruction
实例化 -> 属性赋值 -> 初始化 -> 销毁
Bean 的生命周期图示:
Bean的生命周期 准备对象:
UserLifeCycleTest-启动容器
1 2 3 4 5 6 7 8 9 10 public class UserLifeCycleTest { public static void main (String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("lifecycle.xml" ); User user = applicationContext.getBean(User.class ) ; System.out.println(user); applicationContext.close(); } }
User-实体类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 public class User implements BeanNameAware , BeanFactoryAware , ApplicationContextAware , InitializingBean , DisposableBean { private String name; private int age; public User () { this .name = "laowang" ; this .age = 18 ; System.out.println("======== User Constructor ========" ); } public User (String name, int age) { this .name = name; this .age = age; System.out.println("======== User Constructor [name]" + name + " [age]" + age + " ========" ); } @Override public void setBeanName (String name) { System.out.println("======== User setBeanName【" + name + "】 ========" ); } @Override public void setBeanFactory (BeanFactory beanFactory) throws BeansException { System.out.println("======== User setBeanFactory【" + beanFactory + "】invoke ========" ); } @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException { System.out.println("======== User setApplicationContext【" + applicationContext + "】invoke ========" ); } @PostConstruct public void postConstruct () { System.out.println("======== User postConstruct ========" ); } @Override public void afterPropertiesSet () throws Exception { System.out.println("======== User afterPropertiesSet ========" ); } public void initMethod () { System.out.println("======== User initMethod ========" ); } @PreDestroy public void PreDestroy () { System.out.println("======== User PreDestroy ========" ); } @Override public void destroy () throws Exception { System.out.println("======== User destroy ========" ); } public void destroyMethod () { System.out.println("======== User destroyMethod ========" ); } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } @Override public String toString () { return "User{" + "name='" + name + '\'' + ", age=" + age + '}' ; }
UserInstantiationAwareBeanPostProcessor-User处理类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public class UserInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation (Class<?> beanClass, String beanName) throws BeansException { if (beanClass.equals(User.class )) { System.out.println("======== BeforeInstantiation beanClass【" + beanClass + "】" + "beanName【" + beanName + "】========" ); } return null ; } @Override public boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException { if (bean instanceof User) { System.out.println("======== AfterInstantiation bean【" + bean + "】" + "beanName【" + beanName + "】========" ); } return true ; } @Override public PropertyValues postProcessPropertyValues (PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if (bean instanceof User) { System.out.println("======== PropertyValues【" + pvs + "】 PropertyDescriptor 【" + pds + "】 bean【" + bean + "】" + "beanName【" + beanName + "】========" ); } return pvs; } @Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException { if (bean instanceof User) { System.out.println("======== BeforeInitialization bean【" + bean + "】" + "beanName【" + beanName + "】========" ); } return bean; } @Override public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException { if (bean instanceof User) { System.out.println("======== AfterInitialization bean【" + bean + "】" + "beanName【" + beanName + "】========" ); } return bean; } }
lifecycle.xml配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <context:annotation-config /> y <bean id ="user" class ="com.arsenal.beanlifecycle.User" init-method ="initMethod" destroy-method ="destroyMethod" /> <bean id ="userInstantiationAwareBeanPostProcessor" class ="com.arsenal..UserInstantiationAwareBeanPostProcessor" /> </beans >
执行顺序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ======== BeforeInstantiation beanClass【class com .arsenal .beanlifecycle .User 】beanName 【user 】 ======== ======== User Constructor ======== ======== AfterInstantiation bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== ======== PropertyValues【PropertyValues: length=0 】 PropertyDescriptor 【[Ljava.beans.PropertyDescriptor;@105f ece7】 bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== ======== User setBeanName【user】 ======== ======== User setBeanFactory【org.springframework.beans.factory.support.DefaultListableBeanFactory@184f 6be2: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,user,userInstantiationAwareBeanPostProcessor]; root of factory hierarchy】invoke ======== ======== User setApplicationContext【org.springframework.context.support.ClassPathXmlApplicationContext@7 dc36524: startup date [Sun Sep 20 16 :16 :22 CST 2020 ]; root of context hierarchy】invoke ======== ======== BeforeInitialization bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== ======== User postConstruct ======== ======== User afterPropertiesSet ======== ======== User initMethod ======== ======== AfterInitialization bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== ======== User PreDestroy ======== ======== User destroy ======== ======== User destroyMethod ========
执行详细信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 16 :16 :22.858 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user' 16 :16 :22.858 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'user' ======== BeforeInstantiation beanClass【class com .arsenal .beanlifecycle .User 】beanName 【user 】 ======== ======== User Constructor ======== 16:16:22.860 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Found init method on class [com.arsenal.beanlifecycle.User]: public void com.arsenal.beanlifecycle.User.postConstruct() 16:16:22.860 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Found destroy method on class [com.arsenal.beanlifecycle.User]: public void com.arsenal.beanlifecycle.User.PreDestroy() 16:16:22.860 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Registered init method on class [com.arsenal.beanlifecycle.User]: org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement@a1ab9f17 16:16:22.860 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Registered destroy method on class [com.arsenal.beanlifecycle.User]: org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement@194fb3f7 16 :16 :22.860 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'user' to allow for resolving potential circular references======== AfterInstantiation bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== ======== PropertyValues【PropertyValues: length=0 】 PropertyDescriptor 【[Ljava.beans.PropertyDescriptor;@105f ece7】 bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== ======== User setBeanName【user】 ======== ======== User setBeanFactory【org.springframework.beans.factory.support.DefaultListableBeanFactory@184f 6be2: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,user,userInstantiationAwareBeanPostProcessor]; root of factory hierarchy】invoke ======== ======== User setApplicationContext【org.springframework.context.support.ClassPathXmlApplicationContext@7 dc36524: startup date [Sun Sep 20 16 :16 :22 CST 2020 ]; root of context hierarchy】invoke ======== ======== BeforeInitialization bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== 16 :16 :22.864 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Invoking init method on bean 'user' : public void com.arsenal.beanlifecycle.User.postConstruct()======== User postConstruct ======== 16 :16 :22.864 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking afterPropertiesSet () on bean with name 'user' ======== User afterPropertiesSet ========16 :16 :22.864 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking init method 'initMethod' on bean with name 'user' ======== User initMethod ======== ======== AfterInitialization bean【com.arsenal.beanlifecycle.User@1 b083826】beanName【user】======== 16 :16 :22.864 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'user' 16 :16 :22.864 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userInstantiationAwareBeanPostProcessor' 16 :16 :22.865 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory' 16 :16 :22.881 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Unable to locate LifecycleProcessor with name 'lifecycleProcessor' : using default [org.springframework.context.support.DefaultLifecycleProcessor@3 ee0fea4]16 :16 :22.882 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor' 16 :16 :22.885 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source16 :16 :22.888 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'user' com.arsenal.beanlifecycle.User@1 b083826 16 :16 :22.888 [main] INFO org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@7 dc36524: startup date [Sun Sep 20 16 :16 :22 CST 2020 ]; root of context hierarchy16 :16 :22.888 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor' 16 :16 :22.889 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@184f 6be2: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,user,userInstantiationAwareBeanPostProcessor]; root of factory hierarchy16 :16 :22.889 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Invoking destroy method on bean 'user' : public void com.arsenal.beanlifecycle.User.PreDestroy()======== User PreDestroy ======== 16 :16 :22.889 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy () on bean with name 'user' ======== User destroy ========16 :16 :22.890 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy method 'destroyMethod' on bean with name 'user' ======== User destroyMethod ========
延伸 Spring源码解析 雷丰阳_spring源码 SpringIoc 实现原理 spring-bean-life-cycle Spring Bean的生命周期 深究Spring中Bean的生命周期
<
Cache
Spring IOC
>