After more than a year, he mastered the Spring, SpringBoot, SpringCloud after
Once again, I go back and re-learn the Spring Framework
Bean's life cycle study:
In traditional XML configuration, it can be custom initialization and destruction methods:
init-method="" destroy-method=""
Simple to use annotation mode:
@Configuration public class LifeCircleConfig { @Bean(initMethod = "init",destroyMethod = "destroy") public Car car(){ return new Car(); } }
public class Car { public Car(){ System.out.println("Construct Car!"); } public void init(){ System.out.println("Car init!"); } public void destroy(){ System.out.println("Car destroy!"); } }
public class LifeCircleTest { private static AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeCircleConfig.class); @Test public void test(){ applicationContext.close(); } }
Note: You must close method, it will not print Car Destruction method
Printing is as follows:
Construct Car! Car init! Car destroy!
The default here is a single instance of Bean
If it is multi-instance, then follow the above test code is not printed , because the multi-instance cases, will create an object in the case of acquisition Bean
And in many cases of the case, it will only call the initialization and construction methods, it does not call the methods of destruction
The above test initialization code completion IOC container only, so nothing Print
Spring implement the interface mode: this time does not need to be configured in the @Bean
public class Car implements InitializingBean, DisposableBean { public Car() { System.out.println("Construct Car!"); } public void afterPropertiesSet() throws Exception { System.out.println("Car init!"); } public void destroy() { System.out.println("Car destroy!"); } }
Use native Java annotations:
public class Car { public Car() { System.out.println("Construct Car!"); } @PostConstruct public void init() { System.out.println("Car init!"); } @PreDestroy public void destroy() { System.out.println("Car destroy!"); } }
Spring Bean used in the post-processor:
@Component public class MyBeanPostProcessor implements BeanPostProcessor { /** * 初始化前调用 */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization " + bean + " " + beanName); return bean; } /** * 初始化后调用 */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization " + bean + " " + beanName); return bean; } }
@Configuration @ComponentScan("org.dreamtech.bean") public class LifeCircleConfig { @Bean public Car car(){ return new Car(); } }
After the printing test section as follows:
Construct Car!
postProcessBeforeInitialization org.dreamtech.bean.Car@2d9d4f9d car
postProcessAfterInitialization org.dreamtech.bean.Car@2d9d4f9d car
BeanPostProcessor principle:
View this section of source code:
initializeBean (beanName, exposedObject, mbd) method:
Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { 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); }
Before invokeInitMethods initialization method
Call applyBeanPostProcessorsBeforeInitialization, which is called Before the method of all PostProcessor
After initialization method invokeInitMethods
Call applyBeanPostProcessorsAfterInitialization, which is called After all methods of PostProcessor
Enter applyBeanPostProcessorsBeforeInitialization ways to view source code:
Through all Processor, upon return null, it will be out of the loop
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result; }
Before initializeBean method, a method call is populateBean
Role: assigns them
// Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { exposedObject = initializeBean(beanName, exposedObject, mbd); } }
So: the BeanPostProcessor Bean is after the assignment, before and after the execution of the initialization process
Spring bottom BeanPostProcessor in use:
Get Interface IOC containers:
public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext var1) throws BeansException; }
And it is based on BeanPostProcessor, the code is too long not intercepted
class ApplicationContextAwareProcessor implements BeanPostProcessor
Or a parameter check: to be used BeanPostProcessor
public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean
Part of the code as follows:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!this.afterInitialization) { this.doValidate(bean); } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (this.afterInitialization) { this.doValidate(bean); } return bean; }