Spring core family of beans lifecycle
The last article in the Spring series covered the Spring container and the initialization of the core WebApplicationContext. This section is going to cover the life cycle of beans in the Spring container. I personally think this section is more practical, in the actual work often use these knowledge to solve some very difficult problems. All right, the same old story.
- The life cycle of the Bean in ApplicationContext
1. The lifecycle of the Bean in ApplicationContext
Here’s a picture:
- Green arrows in figure three steps (InstantiationAwareBeanPostProcessor) and the pink arrow two steps (BeanPostProcessor) is a container class life cycle of the interface, as each Spring loaded any Bean into the container, Each of these interfaces makes several calls as shown in the figure. These two processors are called container-level post-processors, and their impact is global, affecting all beans.
- Figure large red circle circle live interface is called “plant level processor”, a similar interface and CustomEditorConfigurer, accomplished, and so on, this kind of interface called when the context is initialized only once, Its purpose is to complete some configuration file processing work.
- The rest is simple, bean-level interfaces that are specific to a Bean, and that each Bean invokes when instantiated.
It is important to note that both container-level post-processors and factory-level post-processors can be configured multiple times (e.g., two Beanpostprocessors), and if you want to control the order in which they are called, Implement a org. Springframework. Core. Ordered interface. Of course, you don’t have to, you only have one post-processor.
Emphasis! The order in which these interfaces are called is not static and can be changed from version to version in Spring. You need to know that you can use these interfaces to perform properties on the Bean when it is initialized. The order of calls should be tested against the specific version. Here’s an example:
public class Student implements BeanFactoryAware.BeanNameAware.InitializingBean.DisposableBean.ApplicationContextAware {
private String name;
public Student(String name) {
this.name = name;
}
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware......");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware......");
}
@Override
public void destroy(a) throws Exception {
System.out.println("DisposableBean......");
}
@Override
public void afterPropertiesSet(a) throws Exception {
System.out.println("InitializingBean......");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware......"); }}Copy the code
BeanFactoryPostProcessor:
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor(a) {
super(a); System.out.println("This is the BeanFactoryPostProcessor implementation class constructor!!");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out.println("BeanFactoryPostProcessor calls the postProcessBeanFactory method");
BeanDefinition bd = arg0.getBeanDefinition("student");
MutablePropertyValues propertyValues = bd.getPropertyValues();
// The information in the configuration file exists as a BeanDefinition when loaded into Spring. This is where you can change the BeanDefinition again, so you can interpret that as changing the contents of the configuration file
// propertyValues.add("zdy","123");}}Copy the code
BeanPostProcessor:
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor(a) {
super(a); System.out.println("This is the BeanPostProcessor implementation class constructor!!");
}
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("BeanPostProcessor interface method After changes properties!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("The BeanPostProcessor interface method Before changes the properties!");
returnarg0; }}Copy the code
InstantiationAwareBeanPostProcessorAdapter:
public class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor(a) {
super(a); System.out.println("This is InstantiationAwareBeanPostProcessorAdapter implementation class constructor!!");
}
// interface method before instantiating the Bean
@Override
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor Before calling");
return null;
}
// interface method, after instantiating the Bean
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor Ater calling");
return bean;
}
// called when the interface method is set to a property
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor postProcessPropertyValues calling");
returnpvs; }}Copy the code
Then our Main method:
public class App
{
public static void main( String[] args )
{
ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu = (Student) ac.getBean("student");
stu.setName("wangwu"); }}Copy the code
Spring files are the simplest :(note that we need to add all our own handlers to the container)
<? The XML version = "1.0" encoding = "utf-8"? > <beans <bean id="student" class="com.zdy.Student"> <constructor-arg value="zhangsan"/> </bean> <bean id="myBeanFactoryPostProcessor" class="com.zdy.MyBeanFactoryPostProcessor"></bean> <bean id="myInstantiationAwareBeanPostProcessor" class="com.zdy.MyInstantiationAwareBeanPostProcessor"></bean> <bean id="myBeanPostProcessor" class="com.zdy.MyBeanPostProcessor"></bean> </beans>Copy the code
Then run and see the result:
Output: This is the BeanFactoryPostProcessor implementation class constructor!! Spring BeanFactoryPostProcessor call postProcessBeanFactory method This is InstantiationAwareBeanPostProcessorAdapter implementation class constructor!!!!! This is the BeanPostProcessor implementation class constructor!! InstantiationAwareBeanPostProcessor call Before method InstantiationAwareBeanPostProcessor call postProcessPropertyValues method BeanNameAware...... BeanFactoryAware...... ApplicationContextAware...... The BeanPostProcessor interface method Before changes the properties! InitializingBean...... InstantiationAwareBeanPostProcessor call Ater method BeanPostProcessor interface method After the properties to change!Copy the code
Spring has added a lot of mechanisms to the Bean creation process in order to expose its internal mechanisms to the user as much as possible. All we need to do is define the logic of the Processor, register it with the Sprinhg container, and Spring will call it. Second, another way is to have our Bean implement some interface (similar to ApplicationContextAware) by calling a method defined by the interface at some stage of Bean initialization to pass in some information. Like ApplicationContextAware just gives us the ApplicationContext.
Then I will tell you a few practical points of knowledge, you remember, when you come back to read it:
- In the above life cycle flow chart, pay attention to the sequence of calls to avoid the phenomenon of attribute overwriting.
- BeanFactoryPostProcessor mainly does something when Spring has just loaded the configuration file and has no time to initialize the Bean. Such as tampering with the configuration of a Bean in a configuration file.
- InstantiationAwareBeanPostProcessorAdapter basic with no bird, Bean after initialization, also called when not set attribute value, like spring BeanFactoryPostProcessor, can tamper with the information in the configuration file loaded into memory.
- ApplicationContextAware: Very useful, injecting ApplicationContext into the Bean.
- InitializingBean: Useful, you can do some customization after all the Bean properties have been changed.
- BeanPostProcessor: it doesn’t work. The Spring framework uses a lot of things internally, like AOP and dynamic proxies. I’ll have time to analyze it later.
- The other methods, such as init-method and destroy, are mostly useless. I haven’t used it much, but I know of it.
conclusion
Well, the Bean life cycle is calculated to share with you, there is nothing, you know there is such a thing, you can come back when the “post-processor” mess up and look at the order. Then there are the interfaces implemented by some beans, the most commonly used being ApplicationContextAware and InitializingBean. There is also the BeanPostProcessor, because this interface’s methods pass in Bean entities as objects. So you can do some property manipulation. In fact, to be honest, programmers use less. It’s mostly used inside the frame. Over, Have a good day!
I don’t think this is a good one, so let’s give you a portal. I feel that it is rougher than I am. Please refer to it (^_^):
- Spring Bean life cycle