1.Spring中bean的生命周期
在spring中,bean是spring
IOC容器实例化、组装和管理的对象,因此spring中的bean的生命周期也由spring管理。
bean的生命周期分为4个阶段为:
实例化 - Instantiation
初始化 - Populate
使用 - Initialization
销毁 - Destruction
2.Bean的生命周期图
3.代码测试
3.1 Person
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 93 94 95 96 package com.xxx.beancycle.instant;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.BeanNameAware;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;@Component public class Person implements InitializingBean , DisposableBean { private String name; private String address; private int phone; public Person () { System.out.println("【构造器】调用Person的构造器实例化" ); } public String getName () { return name; } public void setName (String name) { System.out.println("【注入属性】注入属性name:" + name); this .name = name; } public String getAddress () { return address; } public void setAddress (String address) { System.out.println("【注入属性】注入属性address:" +address); this .address = address; } public int getPhone () { return phone; } public void setPhone (int phone) { System.out.println("【注入属性】注入属性phone:" + phone); this .phone = phone; } @Override public String toString () { return "Person [address=" + address + ", name=" + name + ", phone=" + phone + "]" ; } @PostConstruct public void PostConstruct () { System.out.println("PostConstruct!!" ); } @Override public void afterPropertiesSet () throws Exception { System.out.println("==================" +this ); System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()" ); } public void myInit () { System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法" ); } @PreDestroy public void PreDestroy () { System.out.println("PreDestroy!!" ); } @Override public void destroy () throws Exception { System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()" ); } public void myDestory () { System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法" ); } }
三个属性:name、address、phone。且分别有3个方法@PostConstruct、afterPropertiesSet()、myInit()。针对于bean的初始化方法。同理,有3个方法对应bean销毁调用的方法。
3.2 MyBeanPostProcessor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor () { super (); System.out.println("这是BeanPostProcessor实现类构造器!!" ); } @Override public Object postProcessAfterInitialization (Object arg0, String arg1) throws BeansException { System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性1进行更改!" ); return arg0; } @Override public Object postProcessBeforeInitialization (Object arg0, String arg1) throws BeansException { System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性1进行更改!" ); return arg0; } }
实现BeanPostProcessor
接口,覆写postProcessBeforeInitialization、postProcessAfterInitialization方法。
3.3
MyInstantiationAwareBeanPostProcessor
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 MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { public MyInstantiationAwareBeanPostProcessor () { super (); System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!" ); } @Override public Object postProcessBeforeInstantiation (Class beanClass, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法" ); return null ; } @Override public boolean postProcessAfterInstantiation (Object o, String s) throws BeansException { System.out.println(":=============" +o +"---------" + s); System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法" ); return true ; } @Override public PropertyValues postProcessPropertyValues (PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法" ); return pvs; } }
实现MyInstantiationAwareBeanPostProcessor,只覆写postProcessPropertyValues、postProcessBeforeInstantiation、postProcessAfterInstantiation三个接口。它也实现了BeanPostProcessor
接口,在上文我们已经覆写postProcessBeforeInitialization、postProcessAfterInitialization方法。此处就不用再次覆写。---可以覆写,只不过会先执行BeanPostProcessor的实现类,然后再依次执行。
3.4 spring-config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?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:p ="http://www.springframework.org/schema/p" xmlns:aop ="http://www.springframework.org/schema/aop" xmlns:tx ="http://www.springframework.org/schema/tx" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <bean id ="beanPostProcessor" class =" com.xxx.beancycle.instant.MyBeanPostProcessor" > </bean > <bean id ="instantiationAwareBeanPostProcessor" class =" com.xxx.beancycle.instant.MyInstantiationAwareBeanPostProcessor" > </bean > <bean id ="person" class =" com.xxx.beancycle.instant.Person" init-method ="myInit" destroy-method ="myDestory" > <property name ="name" value ="张三" > </property > <property name ="address" value ="广州" > </property > <property name ="phone" value ="15900" > </property > </bean > </beans >
通过setter注入的方式将上述bean对象注入到ioc容器中。
3.5 Test
1 2 3 4 5 6 7 8 9 @Test public void testBean () { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext ("classpath:com/xxx/beancycle/spring-config.xml" ); System.out.println("容器初始化成功!!!" ); System.out.println("现在开始关闭容器!!!" ); Person bean = applicationContext.getBean("person" , Person.class); System.out.println("-----------" +bean); applicationContext.close(); }
控制台打印如下:
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 17:20:52,762 INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [com/xxx/beancycle/spring-config.xml] 这是BeanPostProcessor实现类构造器!! 这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!! InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法 【构造器】调用Person的构造器实例化 :=============Person [address=null, name=null, phone=0]---------person InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法 InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 【注入属性】注入属性name:张三 【注入属性】注入属性address:广州 【注入属性】注入属性phone:15900 BeanPostProcessor接口方法postProcessBeforeInitialization对属性1进行更改! ==================Person [address=广州, name=张三, phone=15900] 【InitializingBean接口】调用InitializingBean.afterPropertiesSet() 【init-method】调用<bean>的init-method属性指定的初始化方法 BeanPostProcessor接口方法postProcessAfterInitialization对属性1进行更改! 容器初始化成功!!! 现在开始关闭容器!!! -----------Person [address=广州, name=yangxin, phone=177] 17:20:52,892 INFO ClassPathXmlApplicationContext:984 - Closing org.springframework.context.support.ClassPathXmlApplicationContext@3ac3fd8b: startup date [Fri Mar 03 17:20:52 CST 2023]; root of context hierarchy 【DiposibleBean接口】调用DiposibleBean.destory() 【destroy-method】调用<bean>的destroy-method属性指定的初始化方法 Process finished with exit code 0
4.详解日志
4.1 实例化
对应下列日志:
1 2 3 4 5 6 7 这是BeanPostProcessor实现类构造器!! 这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!! InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法 【构造器】调用Person的构造器实例化 :=============Person [address=null, name=null, phone=0]---------person InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法 InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
首先,spring会实例化MyBeanPostProcessor、MyInstantiationAwareBeanPostProcessor这些实现或者继承spring的类。然后再实例化我们定义的"bean",此处实例化Person类时,会优先执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,也就是实例化前置方法。改方法允许我们在实例化对象的时候,可以对bean进行前置处理。然后通过反射实例化对象,
实例化完成之后会调用postProcessAfterInstantiation方法,该方法返回布尔值,如果返回false则不执行postProcessPropertyValues 方法,也就是不会进行属性修改。
剩余的初始化方法会执行,也就是BeanPostProcessor的postProcessBeforeInitialization与postProcessAfterInitialization方法会执行。如果在这些方法里对bean都没有进行任何处理,则该bean的所有属性值均为默认值。
如下是返回false的日志:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!! InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法 【构造器】调用Person的构造器实例化 :=============Person [address=null, name=null, phone=0]---------person InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法 InstantiationAwareBeanPostProcessor调用postProcessBeforeInitialization方法对属性2进行更改 ==================Person [address=null, name=null, phone=0] 【InitializingBean接口】调用InitializingBean.afterPropertiesSet() 【init-method】调用<bean>的init-method属性指定的初始化方法 InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法对属性2进行更改 容器初始化成功!!! 现在开始关闭容器!!! -----------Person [address=null, name=null, phone=0] 17:33:33,215 INFO ClassPathXmlApplicationContext:984 - Closing org.springframework.context.support.ClassPathXmlApplicationContext@3ac3fd8b: startup date [Fri Mar 03 17:33:33 CST 2023]; root of context hierarchy 【DiposibleBean接口】调用DiposibleBean.destory() 【destroy-method】调用<bean>的destroy-method属性指定的初始化方法 ------->打印的Person对象的属性值为空。
4.2 初始化
对应下列日志:
1 2 3 4 5 6 7 8 【注入属性】注入属性name:张三 【注入属性】注入属性address:广州 【注入属性】注入属性phone:15900 BeanPostProcessor接口方法postProcessBeforeInitialization对属性1进行更改! ==================Person [address=广州, name=张三, phone=15900] 【InitializingBean接口】调用InitializingBean.afterPropertiesSet() 【init-method】调用<bean>的init-method属性指定的初始化方法 BeanPostProcessor接口方法postProcessAfterInitialization对属性1进行更改!
我们可以看到在xml里、配置了
1 2 3 4 5 <bean id ="person" class =" com.xxx.beancycle.instant.Person" init-method ="myInit" destroy-method ="myDestory" > <property name ="name" value ="张三" > </property > <property name ="address" value ="广州" > </property > <property name ="phone" value ="15900" > </property > </bean >
通过postProcessPropertyValues方法给bean填充属性、填充的就是我们在xml配置的属性。
aware接口我们暂时不用管。
然后执行BeanPostProcessor的postProcessBeforeInitialization方法,对bean进行初始化前置操作处理。
然后执行初始化方式(上文没有执行@PostConstruct标注的方法是因为我没有让spring扫描Persond对象。因此注解没有生效)
初始化方法优先级:
@PostConstruct --->InitializingBean.afterPropertiesSet()--->xml配置的Init-method
4.3 销毁
对应下列日志:
1 2 【DiposibleBean接口】调用DiposibleBean.destory() 【destroy-method 】调用<bean >的destroy -method 属性指定的初始化方法
销毁方法优先级:
@PreDestroy --->DiposibleBean.destory()--->xml配置的destroy-method
5.BeanFactoryPostProcessor
BeanPostProcessor
InstantiationAwareBeanPostProcessor
这两兄弟可能是Spring扩展中最重要 的两个接口!InstantiationAwareBeanPostProcessor作用于实例化 阶段的前后,BeanPostProcessor作用于初始化 阶段的前后。
说到BeanPostProcessor,不得不提一下BeanFactoryPostProcessor
,BeanFactoryPostProcessor和BeanPostProcessor,这两个接口,都是Spring初始化bean时对外暴露的扩展点。两个接口名称看起来很相似,但作用及使用场景却不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 public interface BeanFactoryPostProcessor { void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) throws BeansException; }
现在我们新写一个类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public MyBeanFactoryPostProcessor () { super (); System.out.println("这是BeanFactoryPostProcessor实现类构造器!!" ); } @Override public void postProcessBeanFactory (ConfigurableListableBeanFactory arg0) throws BeansException { System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法" ); BeanDefinition bd = arg0.getBeanDefinition("person" ); System.out.println("-=-=-=-=-=-=" +bd.getPropertyValues()); System.out.println("-=-=-=-=-=-=" +bd.getPropertyValues().get("address" )); System.out.println("-=-=-=-=-=-=" +bd.getPropertyValues().get("name" )); System.out.println("-=-=-=-=-=-=" +bd.getPropertyValues().get("phone" )); System.out.println("----------:操作bean的定义" ); bd.getPropertyValues().addPropertyValue("phone" , "110" ); } }
并且通过xml注入:
1 <bean id ="beanFactoryPostProcessor" class =" com.xxx.beancycle.instant.MyBeanFactoryPostProcessor" > </bean >
再运行测试类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 这是BeanFactoryPostProcessor实现类构造器!! BeanFactoryPostProcessor调用postProcessBeanFactory方法 -=-=-=-=-=-=PropertyValues: length=3; bean property 'name' ; bean property 'address' ; bean property 'phone' -=-=-=-=-=-=TypedStringValue: value [广州], target type [null] -=-=-=-=-=-=TypedStringValue: value [张三], target type [null] -=-=-=-=-=-=TypedStringValue: value [15900], target type [null] ----------:操作bean的定义 这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!! InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法 【构造器】调用Person的构造器实例化 :=============Person [address=null, name=null, phone=0]---------person InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法 InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 【注入属性】注入属性name:张三 【注入属性】注入属性address:广州 【注入属性】注入属性phone:110 ... ...
我们会发现我们在xml里定义的参数已经被改变了。以前的
【注入属性】注入属性phone:15900
变为【注入属性】注入属性phone:110
。
实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改 ,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
6.Aware接口
为了更好的理解生命周期,我们前面暂时没有解释生命周期图中的第六步,也就是Aware
接口,在此处我们来讲一下Aware接口。我们看一下spring对aware接口的解释:
A marker superinterface indicating that a bean is eligible to be
notified by the Spring container of a particular framework object
through a callback-style method. The actual method signature is
determined by individual subinterfaces but should typically consist of
just one void-returning method that accepts a single argument. Note that
merely implementing Aware provides no default functionality. Rather,
processing must be done explicitly, for example in a BeanPostProcessor.
Refer to ApplicationContextAwareProcessor for an example of processing
specific *Aware interface callbacks.
含义:
一个标记超接口,指示bean有资格通过回调样式方法被Spring容器通知特定框架对象。实际的方法签名由各个子接口确定,但通常只应由一个接受单个参数的返回空值的方法组成。
注意,仅实现Aware不提供默认功能。相反,处理必须显式完成,例如在BeanPostProcessor中。有关处理特定*Aware接口回调的示例,请参阅ApplicationContextAwareProcessor。
代码:
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 93 94 95 96 97 98 99 100 101 102 103 104 import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanClassLoaderAware;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.BeanNameAware;import org.springframework.context.*;import org.springframework.context.annotation.ImportAware;import org.springframework.context.weaving.LoadTimeWeaverAware;import org.springframework.core.env.Environment;import org.springframework.core.io.ResourceLoader;import org.springframework.core.type.AnnotationMetadata;import org.springframework.instrument.classloading.LoadTimeWeaver;import org.springframework.jmx.export.notification.NotificationPublisher;import org.springframework.jmx.export.notification.NotificationPublisherAware;import org.springframework.stereotype.Component;import org.springframework.util.StringValueResolver;import org.springframework.web.context.ServletConfigAware;import org.springframework.web.context.ServletContextAware;import javax.servlet.ServletConfig;import javax.servlet.ServletContext;@Component public class AllAwareInterface implements BeanNameAware , BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, ServletContextAware, LoadTimeWeaverAware, ImportAware , NotificationPublisherAware, ServletConfigAware, ApplicationStartupAware { @Override public void setBeanName (String name) { System.out.println("1 我是 BeanNameAware 的 setBeanName 方法 ---参数:name,内容:" + name); } @Override public void setBeanClassLoader (ClassLoader classLoader) { System.out.println("2 我是 BeanClassLoaderAware 的 setBeanClassLoader 方法" ); } @Override public void setBeanFactory (BeanFactory beanFactory) throws BeansException { System.out.println("3 我是 BeanFactoryAware 的 setBeanFactory 方法" ); } @Override public void setEnvironment (Environment environment) { System.out.println("4 我是 EnvironmentAware 的 setEnvironment 方法" ); } @Override public void setEmbeddedValueResolver (StringValueResolver stringValueResolver) { System.out.println("5 我是 EmbeddedValueResolverAware 的 setEmbeddedValueResolver 方法" ); } @Override public void setResourceLoader (ResourceLoader resourceLoader) { System.out.println("6 我是 ResourceLoaderAware 的 setResourceLoader 方法" ); } @Override public void setApplicationEventPublisher (ApplicationEventPublisher applicationEventPublisher) { System.out.println("7 我是 ApplicationEventPublisherAware 的 setApplicationEventPublisher 方法" ); } @Override public void setMessageSource (MessageSource messageSource) { System.out.println("8 我是 MessageSourceAware 的 setMessageSource 方法" ); } @Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException { System.out.println("9 我是 ApplicationContextAware 的 setApplicationContext 方法" ); } @Override public void setServletContext (ServletContext servletContext) { System.out.println("10 我是 ServletContextAware 的 setServletContext 方法" ); } @Override public void setLoadTimeWeaver (LoadTimeWeaver loadTimeWeaver) { System.out.println("11 我是 LoadTimeWeaverAware 的 setLoadTimeWeaver 方法" ); } @Override public void setImportMetadata (AnnotationMetadata annotationMetadata) { System.out.println("12 我是 ImportAware 的 setImportMetadata 方法" ); } @Override public void setNotificationPublisher (NotificationPublisher notificationPublisher) { System.out.println("13 我是 NotificationPublisherAware 的 setNotificationPublisher 方法" ); } @Override public void setServletConfig (ServletConfig servletConfig) { System.out.println("14 我是 ServletConfigAware 的 setServletConfig 方法" ); } @Override public void setApplicationStartup (ApplicationStartup applicationStartup) { System.out.println("15 我是 ApplicationStartupAware 的 setApplicationStartup 方法" ); } }
spring中所有的aware
接口:
ApplicationEventPublisherAware
,
ApplicationStartupAware
, BeanClassLoaderAware
,
BeanFactoryAware
, BeanNameAware
,
EmbeddedValueResolverAware
, EnvironmentAware
,
ImportAware
, LoadTimeWeaverAware
,
MessageSourceAware
,
NotificationPublisherAware
,
ResourceLoaderAware
, SchedulerContextAware
,
ServletConfigAware
, ServletContextAware
本着最简单的原则,本文不会讲aware接口全部讲解,只讲最常用的aware接口。
6.1 ApplicationContextAware
该接口是最常用的一个注解,通过实现ApplicationContextAware接口,我们能够得到applicationContext,因此我们可以再spring容器启动的试试,对容器进行处理。
6.2 ApplicationStartupAware
通过实现ApplicationStartupAware接口,可以在容器启动成功后,通过ApplicationStartup进行相应处理。
6.3 BeanFactoryAware
让Bean获取配置他们的BeanFactory的引用。
6.4 BeanNameAware
调用BeanNameAware接口的实现类中的setBeanName方法,获取容器中 Bean
的名称,
6.5 EnvironmentAware
实现了EnvironmentAware接口重写setEnvironment方法后,在工程启动时可以获得application.properties
、xml、yml 的配置文件配置的属性值。
7. 总结
spring生命周期
总结:
spring的生命周期分为实例化
、属性赋值
、初始化
、销毁
如果 BeanFactoryPostProcessor 和 Bean 关联,
则调用postProcessBeanFactory方法.(即首先尝试从Bean工厂中获取Bean )
如果 InstantiationAwareBeanPostProcessor 和 Bean
关联,则调用postProcessBeforeInstantiation方法
根据配置情况调用 Bean 构造方法实例化 Bean 。
如果 InstantiationAwareBeanPostProcessor 和 Bean
关联,则调用postProcessAfterInstantiation方法和postProcessPropertyValues方法(前几个版本叫postProcessProperty)
调用setter方法完成 Bean 中属性注入 。
调用xxxAware接口
第一类Aware接口
如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的
setBeanName() 方法传入当前 Bean 的 id 值。
如果 Bean 实现了 BeanClassLoaderAware 接口,则 Spring 调用
setBeanClassLoader() 方法传入classLoader的引用。
如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用
setBeanFactory() 方法传入当前工厂实例的引用。
第二类Aware接口
如果 Bean 实现了 EnvironmentAware 接口,则 Spring 调用
setEnvironment() 方法传入当前 Environment 实例的引用。
如果 Bean 实现了 EmbeddedValueResolverAware 接口,则 Spring 调用
setEmbeddedValueResolver() 方法传入当前 StringValueResolver
实例的引用。
如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用
setApplicationContext() 方法传入当前 ApplicationContext
实例的引用。
... ...
如果 BeanPostProcessor
和 Bean 关联,则 Spring
将调用该接口的预初始化方法
postProcessBeforeInitialzation()
对 Bean
进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
Bean初始化前置方法
如果 Bean有执行@PostConstruct注解的方法,则调用该初始化方法。
如果 Bean 实现了InitializingBean
接口,则 调用
afterPropertiesSet()
方法。
如果在配置文件中通过 init-method
属性指定了初始化方法,则调用该初始化方法。
如果 BeanPostProcessor 和 Bean 关联,则 Spring
将调用该接口的初始化方法
postProcessAfterInitialization()
。此时,Bean
已经可以被应用系统使用了。
如果在 <bean>
中指定了该 Bean 的作用范围为
scope="singleton",则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring
对该 Bean 的生命周期管理;如果在 <bean>
中指定了该
Bean 的作用范围为 scope="prototype",则将该 Bean
交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
Bean销毁前置方法
如果 Bean有执行@PreDestroy注解的方法,则调用该初始化方法。
如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory()
方法将 Spring 中的 Bean 销毁
如果在配置文件中通过 destory-method 属性指定了 Bean
的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类 :(结合上图,需要有如下顶层思维)
Bean自身的方法 :
这个包括了Bean本身调用的方法和通过配置文件中<bean>
的init-method和destroy-method指定的方法
Bean级生命周期接口方法 :
这个包括了BeanNameAware、BeanFactoryAware、ApplicationContextAware;当然也包括InitializingBean和DiposableBean这些接口的方法(可以被@PostConstruct和@PreDestroy注解替代 )
容器级生命周期接口方法 :
这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor
这两个接口实现,一般称它们的实现类为“后处理器”。
工厂后处理器接口方法 :
这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor,
CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
8.Read more
:lollipop::https://blog.csdn.net/caihaijiang/article/details/35552859
:lollipop::https://www.cnblogs.com/zrtqsk/p/3735273.html
:lollipop::https://pdai.tech/md/spring/spring-x-framework-ioc-source-3.html
博客说明
文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,不用于任何的商业用途。如有侵权,请联系本人删除。谢谢!