@survivorZzz
2019-07-05T01:08:10.000000Z
字数 20278
阅读 807
Spring
Spring 容器中 Bean的单例和多例大家应该都知道, 默认的, 注册到容器中的Bean是单例的,每一次从容器中获取这个Bean实例, 内存地址都是同一个 举证(亲测):
代码块1:
有这样一个类:
public class MyClass implements InitializingBean, DisposableBean, BeanNameAware {private String beanName;public String getBeanName() {return beanName;}static {System.err.println(">>>>>>>>> static block");}{System.err.println(">>>>>>>>> non-static block");}@Overridepublic void afterPropertiesSet() throws Exception {System.err.println(">>>>>>>>> afterPropertiesSet method!");}@PostConstructvoid method() {System.err.println(">>>>>>>>> postConstruct method!");}@PreDestroyvoid preDestroy() {System.err.println(">>>>>>>>> preDestroy method!");}public void init() {System.err.println(">>>>>>>>> init method!");}public void destroyMethod() {System.err.println(">>>>>>>>> destroyMethod method!");}@Overridepublic void destroy() {System.err.println(">>>>>>>>> override destroy method!");}@Overridepublic void setBeanName(String s) {this.beanName = s;}}
代码块2:
@SpringBootApplication//@ImportResource("springmvc.xml")public class DemoApplication implements ApplicationContextAware{static ApplicationContext applicationContext;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);Object myClass1 = applicationContext.getBean(MyClass.class);Object myClass2 = applicationContext.getBean(MyClass.class);System.out.println(">>>>>>> 相等吗? " + (myClass1 == myClass2));}@Beanpublic MyClass myClass() {return new MyClass();}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if(this.applicationContext == null) {this.applicationContext = applicationContext;}}}
输出:
>>>>>>>>> static block>>>>>>>>> non-static block>>>>>>>>> postConstruct method!>>>>>>>>> afterPropertiesSet method!>>>>>>>>> init method!>>>>>>> 相等吗? true
亲测, 默认的单例是容器一起来之后就立即实例化(lazy = false)的, 也就是说, 我把断点打在代码块2的第9行, 程序还没有跑到第9行的时候就已经打印出了前5行.
单例的Bean可以延迟实例化, 在@Bean注释下使用@Lazy(关于@Lazy的详细用法可以参考该注解的doc)后, 同样还是在代码块2的第9行断点, 当执行第9行的时候才会打印出以上输出的前5行.
测一测多例, 我们在@Bean注解下标注@Scope("prototype"), 代码块2变成:
代码块3:
@SpringBootApplication//@ImportResource("springmvc.xml")public class DemoApplication implements ApplicationContextAware{static ApplicationContext applicationContext;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);MyClass myClass1 = applicationContext.getBean(MyClass.class);MyClass myClass2 = applicationContext.getBean(MyClass.class);System.out.println(">>>>>>> 相等吗? " + (myClass1 == myClass2));}@Bean(initMethod = "init", destroyMethod = "destroyMethod")@Scope("prototype")public MyClass myClass() {return new MyClass();}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if(this.applicationContext == null) {this.applicationContext = applicationContext;}}}
输出:
>>>>>>>>> static block>>>>>>>>> non-static block>>>>>>>>> postConstruct method!>>>>>>>>> afterPropertiesSet method!>>>>>>>>> init method!>>>>>>>>> non-static block>>>>>>>>> postConstruct method!>>>>>>>>> afterPropertiesSet method!>>>>>>>>> init method!>>>>>>> 相等吗? false
可以看到多例模式的Bean, 每次去容器中取到的都是一个新对象, 他们的内存地址不一样! 并且, 从输出的1-9行看出, 实例化了两次!
再来测一测多例的延迟实例化问题, 当我把断点打在代码块3的第9行, 程序跑完第8行准备跑第9行的时候, 控制台均没有输出, 当跑完第9行后, 控制台打印:
>>>>>>>>> static block>>>>>>>>> non-static block>>>>>>>>> postConstruct method!>>>>>>>>> afterPropertiesSet method!>>>>>>>>> init method!
接着执行完第10行后打印:
>>>>>>>>> non-static block>>>>>>>>> postConstruct method!>>>>>>>>> afterPropertiesSet method!>>>>>>>>> init method!
可以看出, 多例模式的Bean是延迟实例化的, 只有从容器中取Bean实例并引用它时才会去实例化它, 并且是每取一次, 就实例化一个对象出来.
那么问题来了, 如果我在多例的Bean上加上@Lazy(false)之后, 会不会在容器一起来之后就去实例化一次呢?
加了@Lazy(false)之后,在代码块3的第9行打断点, 当即将跑第9行时, 查看控制台, 并没有任何输出, 跑完第九行才打印出:
>>>>>>>>> static block>>>>>>>>> non-static block>>>>>>>>> postConstruct method!>>>>>>>>> afterPropertiesSet method!>>>>>>>>> init method!
说明对于多例的Bean来说, 延迟实例化策略对多例Bean无意义. 多例Bean 都是延迟实例化的!
接着, 来探讨一下Spring容器中的Bean的生命周期.
直接上我自己的测试代码:
代码块1:
有这样一个Class定义:
public class MyClass implements InitializingBean, DisposableBean, BeanNameAware {private String beanName;private int age;private String address;public MyClass() {System.err.println(">>>>>>>>>>> MyClass 无参数的构造方法执行!");}public MyClass(int age, String address) {System.err.println(">>>>>>>>>>> MyClass 带参数的构造方法执行!");this.age = age;this.address = address;}static {System.err.println(">>>>>>>>> 静态代码块执行");}{System.err.println(">>>>>>>>> 非静态代码块执行");}@Overridepublic void afterPropertiesSet() throws Exception {System.err.println(">>>>>>>>> 重写InitializingBean的afterPropertiesSet执行!");}@PostConstructvoid method() {System.err.println(">>>>>>>>> @PostConstruct标注的方法执行!");}@PreDestroyvoid preDestroy() {System.err.println(">>>>>>>>> @PreDestroy标注的方法执行!");}public void init() {System.err.println(">>>>>>>>> 自定义的init方法执行!");}public void destroyMethod() {System.err.println(">>>>>>>>> 自定义的destroy方法执行!");}@Overridepublic void destroy() {System.err.println(">>>>>>>>> 重写DisposableBean的destroy方法执行!");}@Overridepublic void setBeanName(String s) {System.err.println(">>>>>>>>> 重写BeanNameAware的setBeanName方法执行!");this.beanName = s;}public int getAge() {return age;}public void setAge(int age) {this.age = age;System.err.println(">>>>>>>>> MyClass 的setAge方法执行 set age = "+age+"!");}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;System.err.println(">>>>>>>>> MyClass 的setAddress方法执行 set address = "+address+"!");}public String getBeanName() {return beanName;}}
代码块2
org.springframework.beans.factory.config.BeanPostProcessor的实现类:
public class MyBeanPostPrecessor implements BeanPostProcessor {public MyBeanPostPrecessor() {super();System.err.println(">>>>>>>> BeanPostProcessor 实现类的 构造 方法执行");}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if(!(bean instanceof MyClass)) {return bean;}System.err.println(">>>>>>>> BeanPostProcessor 实现类的 postProcessBeforeInitialization 方法执行");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if(!(bean instanceof MyClass)) {return bean;}System.err.println(">>>>>>>> BeanPostProcessor 实现类的 postProcessAfterInitialization 方法执行");return bean;}}
代码块3
org.springframework.beans.factory.config.BeanFactoryPostProcessor实现类:
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {public MyBeanFactoryPostProcessor() {super();System.err.println(">>>>>>>> BeanFactoryPostProcessor 实现类的 构造 方法执行");}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {System.err.println(">>>>>>>> BeanFactoryPostProcessor 实现类的 postProcessBeanFactory 方法执行");// String[] beanDefinitionNames = configurableListableBeanFactory.getBeanDefinitionNames();// for(String bd : beanDefinitionNames) {// //一些获取bean 定义信息的方法...// BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(bd);// MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();// ConstructorArgumentValues constructorArgumentValues = beanDefinition.getConstructorArgumentValues();// String scope = beanDefinition.getScope();// // 一些修改Bean 定义信息的方法...// beanDefinition.setLazyInit(true);// beanDefinition.setScope("singleton");// }}}
代码块4
InstantiationAwareBeanPostProcessorAdapter适配器的子类:
public class MyInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter {public MyInstantiationAwareBeanPostProcessorAdapter() {super();System.err.println(">>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 构造 方法执行");}@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {if(beanClass.isAssignableFrom(MyClass.class) || "myClass".equals(beanName)) {System.err.println(">>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 方法执行");}return super.postProcessBeforeInstantiation(beanClass, beanName);}@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {if(bean instanceof MyClass || "myClass".equals(beanName)) {System.err.println(">>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessAfterInstantiation(Object bean, String beanName) 方法执行");}return super.postProcessAfterInstantiation(bean, beanName);}@Overridepublic PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {if(bean instanceof MyClass || "myClass".equals(beanName)) {System.err.println(">>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessPropertyValues 方法执行,PropertyValues: "+ pvs.toString()+"");}return pvs;}}
代码块5
SpringBoot工程的启动类:
@SpringBootApplication//@ImportResource("springmvc.xml")public class DemoApplication implements ApplicationContextAware, BeanFactoryAware {static ApplicationContext applicationContext;static BeanFactory beanFactory;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);MyClass myClass = applicationContext.getBean(MyClass.class);BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry)DemoApplication.applicationContext;DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory)DemoApplication.beanFactory;BeanDefinition beanDefinition = defaultListableBeanFactory.getBeanDefinition(myClass.getBeanName());//从容器中移除MyClass的beanbeanDefinitionRegistry.removeBeanDefinition(myClass.getBeanName());// MyClass myClass1 = applicationContext.getBean(MyClass.class);// System.err.println(myClass1.getBeanName());// 再次手动注册MyClassbeanDefinitionRegistry.registerBeanDefinition(myClass.getBeanName(), beanDefinition);MyClass myClass2 = applicationContext.getBean(MyClass.class);System.err.println(">>>>>>>>> " + myClass2.getBeanName());}@Bean(initMethod = "init", destroyMethod = "destroyMethod")// @Scope("prototype")// @Lazy(false)public MyClass myClass() {return new MyClass(100, "广东");}@Beanpublic MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {return new MyBeanFactoryPostProcessor();}@Beanpublic MyBeanPostPrecessor myBeanPostPrecessor() {return new MyBeanPostPrecessor();}@Beanpublic MyInstantiationAwareBeanPostProcessorAdapter myInstantiationAwareBeanPostProcessorAdapter() {return new MyInstantiationAwareBeanPostProcessorAdapter();}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if(DemoApplication.applicationContext == null) {DemoApplication.applicationContext = applicationContext;}}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {if(DemoApplication.beanFactory == null) {DemoApplication.beanFactory = beanFactory;}}}
启动代码块5后控制台输出:
Connected to the target VM, address: '127.0.0.1:11931', transport: 'socket'. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.0.6.RELEASE)>>>>>>>> BeanFactoryPostProcessor 实现类的 构造 方法执行>>>>>>>> BeanFactoryPostProcessor 实现类的 postProcessBeanFactory 方法执行>>>>>>>> BeanPostProcessor 实现类的 构造 方法执行>>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 构造 方法执行>>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 方法执行>>>>>>>>> 静态代码块执行>>>>>>>>> 非静态代码块执行>>>>>>>>>>> MyClass 带参数的构造方法执行!>>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessAfterInstantiation(Object bean, String beanName) 方法执行>>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessPropertyValues 方法执行,PropertyValues: PropertyValues: length=0>>>>>>>>> 重写BeanNameAware的setBeanName方法执行!>>>>>>>> BeanPostProcessor 实现类的 postProcessBeforeInitialization 方法执行>>>>>>>>> @PostConstruct标注的方法执行!>>>>>>>>> 重写InitializingBean的afterPropertiesSet执行!>>>>>>>>> 自定义的init方法执行!>>>>>>>> BeanPostProcessor 实现类的 postProcessAfterInitialization 方法执行>>>>>>>>> @PreDestroy标注的方法执行!>>>>>>>>> 重写DisposableBean的destroy方法执行!>>>>>>>>> 自定义的destroy方法执行!>>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 方法执行>>>>>>>>> 非静态代码块执行>>>>>>>>>>> MyClass 带参数的构造方法执行!>>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessAfterInstantiation(Object bean, String beanName) 方法执行>>>>>>>> 自定义的InstantiationAwareBeanPostProcessorAdapter 子类的 postProcessPropertyValues 方法执行,PropertyValues: PropertyValues: length=0>>>>>>>>> 重写BeanNameAware的setBeanName方法执行!>>>>>>>> BeanPostProcessor 实现类的 postProcessBeforeInitialization 方法执行>>>>>>>>> @PostConstruct标注的方法执行!>>>>>>>>> 重写InitializingBean的afterPropertiesSet执行!>>>>>>>>> 自定义的init方法执行!>>>>>>>> BeanPostProcessor 实现类的 postProcessAfterInitialization 方法执行>>>>>>>>> myClass
这里说一下org.springframework.beans.factory.config.BeanPostProcessor接口, 它是一个顶层接口, 该接口定义如下:
public interface BeanPostProcessor {default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}
该接口的许多Spring内置的实现类例如AutowiredAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor,ServletContextAwareProcessor是Spring 容器启动时, 容器自己实例化并调用的,例如AutowiredAnnotationBeanPostProcessor用于扫描一个Bean中被@AntoWired标注的成员属性或setter方法或构造器以在实例化Bean时进行依赖注入. 从以上的控制台输出顺序可以看到, 该接口的postProcessBeforeInitialization方法和postProcessAfterInitialization方法在Bean的生命周期的执行顺序为:
1. Bean的构造方法, 此时Bean的实例已经创建(亲测, 可以自己debug试试看)
2. `BeanPostProcessor`的`postProcessBeforeInitialization`方法
3. Bean类中`@PostConstruct`标注的方法(如果有)
4. Bean类中重写`InitializingBean`接口的`afterPropertiesSet()`方法(如果有)
5. Bean中自定义的`init`方法, 并在`@Bean(initMethod = 'init')`指定(如果有)
6. `BeanPostProcessor`的`postProcessAfterInitialization`方法
以上顺序, 对实例化在Spring容器中的Bean都适用, 也就是说, 以上代码块3中的两个方法在每一个Bean实例化之后都会执行, 所以, 可以通过自定义该接口的实现类来对实例化后的对象做一些操作. Spring本身已经提供很多实现类, 具体功能, 可自己源码探索.
再接着, 顺带再说一下另一个BeanPostProcessor的子接口InstantiationAwareBeanPostProcessor, 该子接口除了具备BeanPostProcessor的两个方法定义之外, 还有以下几个方法:
//该方法在构造方法执行之前(Bean实例化之前)执行default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}//该方法在构造方法执行之后(Bean实例化后)执行default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}//该方法在属性注入时可对注入的属性进行操作default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}
以上代码中注释所说的意思, 从以上控制台输出中可以得到验证.该接口有一个适配器**InstantiationAwareBeanPostProcessorAdapter, 可以继承该适配器,重写里面的方法对Bean实例化前后的时间点做一些操作.
接着再说一下和Bean的生命周期无关, 但是和Spring 容器的生命周期有关的BeanFactoryPostProcessor接口.该接口定义如下:
@FunctionalInterfacepublic interface BeanFactoryPostProcessor {/*** Modify the application context's internal bean factory after its standard* initialization. All bean definitions will have been loaded, but no beans* will have been instantiated yet. This allows for overriding or adding* properties even to eager-initializing beans.* @param beanFactory the bean factory used by the application context* @throws org.springframework.beans.BeansException in case of errors*/void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}
从以上的控制台输出顺序可以看出, 该接口实现类的postProcessBeanFactory方法是在Bean初始化之前执行的, 查看该接口方法的注释可知该方法是在所有的Bean定义信息加载但还没有任何Bean被实例化时执行的.那问题就来了, 这个接口和BeanPostProcessor接口有什么区别?以及使用场景如何呢?
BeanFactoryPostProcessor的实现类是作为我们常说的Spring Bean来实例化, 但是这些实现类的对象不作为其他Bean生命周期的一部分, 而是Spring 容器生命周期的一部分.由于BeanFactoryPostProcessor的postProcessBeanFactory被回调的时机是在Bean定义信息被加载时, 在其他Bean被实例化前. 所以你可以在获取到所有的Bean定义, 并修改或重写一些某些Bean 定义,即使是"eager-initializing"的Bean 定义也可以在这个时候修改, 例如这个例子:
public class CustomBeanFactory implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {System.err.println(">>>>>>>> BeanFactoryPostProcessor 实现类的 postProcessBeanFactory 方法执行");String[] beanDefinitionNames = configurableListableBeanFactory.getBeanDefinitionNames();for(String bd : beanDefinitionNames) {//一些获取bean 定义信息的方法...BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(bd);MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();ConstructorArgumentValues constructorArgumentValues = beanDefinition.getConstructorArgumentValues();String scope = beanDefinition.getScope();// 一些修改Bean 定义信息的方法...beanDefinition.setLazyInit(true);beanDefinition.setScope("singleton");}}}
BeanPostProcessor中的两个方法是在Bean实例已经创建之后执行.
顺带再记录一下看源码过程中, SpringBoot启动的时候做的一些事情.
SpringBoot通过SpringApplication.run(DemoApplication.class, args);开始启动Spring, 经过若干操作之后调用了SpringApplication类中public ConfigurableApplicationContext run(String... args)方法,该方法如下:
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();this.configureHeadlessProperty();SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting();Collection exceptionReporters;try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);this.configureIgnoreBeanInfo(environment);Banner printedBanner = this.printBanner(environment);context = this.createApplicationContext();exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);this.refreshContext(context);this.afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);}listeners.started(context);this.callRunners(context, applicationArguments);} catch (Throwable var10) {this.handleRunFailure(context, var10, exceptionReporters, listeners);throw new IllegalStateException(var10);}try {listeners.running(context);return context;} catch (Throwable var9) {this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);throw new IllegalStateException(var9);}}
额外的, 注意这个方法的16行, 创建一个ApplicationContext接口的实现类org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext对象(看源码可知, 只要classpath路径中包含javax.servlet.Servlet和 org.springframework.web.context.ConfigurableWebApplicationContext 就会创建这个类型的ApplicationContext对象作为上下文).
19行this.refreshContext(context), 这段代码之后做的事情就是将生成的ApplicationContext对象强转成org.springframework.context.support.AbstractApplicationContext, 然后调用这个抽象类的org.springframework.context.support.AbstractApplicationContext#refresh方法, 该方法体部分代码如下(没有贴try-catch块):
public void refresh() throws BeansException, IllegalStateException {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}
看第6行和第9行,第6行所做的事情就是依照顺序执行了注册在上下文中的所有BeanFactoryPostProcessor 接口的对象的void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) 方法以在BeanDefinition被容器加载时做一些操作,包括我自定义的'MyBeanFactoryPostProcessor'的postProcessBeanFactory方法, 这些BeanFactoryPostProcessor对象的执行有顺序, 如何排序, 可追踪以上代码块中invokeBeanFactoryPostProcessors(beanFactory);方法的执行, 不再多说.
第9行, 所做的事情就是将所有的BeanPostProcessor接口的实现类对象注册到beanFactory上, 以在接下来容器实例化Bean之后按照一定顺序执行实例化post和after方法, 至于我这里所谓的顺序,详情可追踪这段代码的执行.
总结
Spring 容器从启动到用户从容器中取一个Bean对象实例并引用它这个过程做个简单的总结, 顺序如下:
1. 注册到容器中的所有接口BeanFactoryPostProcessor(该接口的主要作用是可以在Bean实例化之前, 修改已经加载的BeanDefinition)的实现类被实例化.
2. 1中所指的实例化对象按照顺序执行postProcessBeanFactory方法.
3. 所有注册到容器中的BeanPostProcessor的实现类被实例化.
4. 在一个普通Bean被容器实例化之前, BeanPostProcessor接口的子接口InstantiationAwareBeanPostProcessor的实现类的实例化对象的postProcessBeforeInstantiation方法执行.
5. 一个普通Bean的静态代码块被执行(意味着类加载器开始加载这个类的.class文件)
6. 一个普通Bean被容器实例化, 先执行非静态代码块, 再执行构造方法.
7. InstantiationAwareBeanPostProcessor的实现类的实例化对象的postProcessAfterInstantiation方法执行.
8. InstantiationAwareBeanPostProcessor的实现类的实例化对象的postProcessPropertyValues方法执行.
9. 如果该普通Bean实现了Aware接口的子接口, 例如BeanNameAware, 则这些aware接口的方法执行.
10. 注册到容器中的各个接口BeanPostProcessor的的实现类的postProcessBeforeInitialization方法执行.
11. 普通Bean中@PostConstruct标注的方法执行(如果有).
12. 如果普通Bean实现了InitializingBean接口, 则afterPropertiesSet方法执行.
13. 自定义的init方法执行!
14. BeanPostProcessor 实现类的 postProcessAfterInitialization 方法执行.
15. 从容器中移除一个Bean
15. @PreDestroy标注的方法执行(如果有).
16. 如果普通Bean实现了DisposableBean接口则destroy方法执行.
17. 自定义的destroy方法执行!
欢迎各位大佬多多交流, 不正之处欢迎指正!
书写不易, 如想转载请 注明原文地址:
https://www.zybuluo.com/survivorZzz/note/1314637