Several ways to start the spring loader are described

  • 2020-06-23 00:13:15
  • OfStack

There are three ways to define the operations done before the spring container initializes bean and destroys it:

Type 1: Annotate the @PostConstruct and @PreDestroy methods to do what you did before initializing and destroying bean


import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 
 
public class DataInitializer{  
 @PostConstruct 
 public void initMethod() throws Exception { 
  System.out.println("initMethod  Be performed "); 
 } 
 @PreDestroy 
 public void destroyMethod() throws Exception { 
  System.out.println("destroyMethod  Be performed "); 
 } 
} 

The second is by defining init-ES13en and ES14en-ES15en methods in xml


public class DataInitializer{ 
 public void initMethod() throws Exception { 
  System.out.println("initMethod  Be performed "); 
 } 
 public void destroyMethod() throws Exception { 
  System.out.println("destroyMethod  Be performed "); 
 } 
} 


<bean id="dataInitializer" class="com.somnus.demo.DataInitializer" init-method="initMethod" destory-method="destroyMethod"/> 

The third is to implement the InitializingBean and DisposableBean interfaces via bean


import org.springframework.beans.factory.DisposableBean; 
 
public class DataInitializer implements InitializingBean . DisposableBean{ 
  
 @Override 
 public void afterPropertiesSet() throws Exception { 
  System.out.println("afterPropertiesSet  Be performed "); 
 } 
  
 @Override 
 public void destroy() throws Exception { 
  System.out.println("destroy  Be performed "); 
 } 
 
} 

The first and the second are in the same form, only one xml configuration, and the other is in the form of annotations. The big difference is the third one. If a method is initialized in both ways with the same bean, the execution order will be reflected first.

Execute afterPropertiesSet() first, initMethod() later

Let's look at the source code here

How does this work in spring?

You can see why by looking at spring's source code class for loading bean (AbstractAutowireCapableBeanFactory)

invokeInitMethods in AbstractAutowireCapableBeanFactory class explained very clearly, the source code is as follows:


protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) 
  throws Throwable { 
 // Determine whether the bean Is it implemented? Is it implemented InitializingBean Interface, if implemented InitializingBean Interface, just drop the call bean the afterPropertiesSet methods  
 boolean isInitializingBean = (bean instanceof InitializingBean); 
 if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { 
  if (logger.isDebugEnabled()) { 
   logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); 
  } 
  
  if (System.getSecurityManager() != null) { 
   try { 
    AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { 
     public Object run() throws Exception { 
      // Direct call afterPropertiesSet 
      ((InitializingBean) bean).afterPropertiesSet(); 
      return null; 
     } 
    },getAccessControlContext()); 
   } catch (PrivilegedActionException pae) { 
    throw pae.getException(); 
   } 
  }     
  else { 
   // Direct call afterPropertiesSet 
   ((InitializingBean) bean).afterPropertiesSet(); 
  } 
 } 
 if (mbd != null) { 
  String initMethodName = mbd.getInitMethodName(); 
  // Determines whether it is specified init-method Method if specified init-method Method, then call the specified init-method 
  if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && 
    !mbd.isExternallyManagedInitMethod(initMethodName)) { 
    // Into the 1 Step to view the source of the method, you can find init-method The method specified in the method is implemented by reflection  
   invokeCustomInitMethod(beanName, bean, mbd); 
  } 
 } 

Conclusion:

1: spring provides bean with two ways to initialize bean, implementing the InitializingBean interface and implementing the afterPropertiesSet method, or specifying both in the configuration file as ES64en-ES65en

2: Implementing the InitializingBean interface calls the afterPropertiesSet method directly, which is more efficient than calling the method specified by ES70en-ES71en through reflection. However, init-ES73en eliminates the dependence on spring

3: If an error occurs while calling the afterPropertiesSet method, the method specified by ES78en-ES79en is not called.


Related articles: