Spring Learns Again

More than a year later, after mastering Spring, Spring Boot and Spring Cloud

I'll go back and learn the Spring framework again.

 

Bean's life cycle learning:

In traditional XML configurations, initialization and destruction methods can be customized as follows:

init-method="" destroy-method=""

 

Simple use of annotations:

@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: There is a close method, otherwise the Car destruction method will not be printed.

 

Print as follows:

Construct Car!
Car init!
Car destroy!

 

The default here is a single instance Bean

If there are multiple instances, the above test code will not print, because in the case of multiple instances, the object will be created only if the Bean is captured.

In many cases, only initialization and construction methods are invoked, and destruction methods are not invoked.

The above test code only completes the initialization of the IOC container, so nothing is printed.

 

Implementing interfaces in Spring: There is no need to configure in @Bean at this time

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!");
    }

}

 

Using Java native 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!");
    }

}

 

Using Bean's post processor in Spring:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * Pre-initialization call
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization " + bean + " " + beanName);
        return bean;
    }

    /**
     * Initialized call
     */
    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 test, the part is printed as follows:

Construct Car!
postProcessBeforeInitialization org.dreamtech.bean.Car@2d9d4f9d car
postProcessAfterInitialization org.dreamtech.bean.Car@2d9d4f9d car

 

BeanPost Processor Principle:

Look at this source code:

In the 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

ApplyBeanPostProcessors BeforeInitialization is called, that is, the Before method of all PostProcessors is called.

After invokeInitMethods initialization method

ApplyBeanPostProcessors AfterInitialization is called, that is, all PostProcessor's AfterInitialization methods are called.

 

Enter the applyBeanPostProcessors BeforeInitialization method to view the source code:

Traversing through all Processor s, once you return to null, you jump 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 the initializeBean method, the populateBean method was called

Function: assign values to attributes

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }

 

So: BeanPostProcessor is executed before and after Bean assignment and initialization

 

BeanPost Processor's use at the bottom of Spring:

Get the interface of the IOC container:

public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext var1) throws BeansException;
}

It's based on BeanPostProcessor, and code is too long to intercept.

class ApplicationContextAwareProcessor implements BeanPostProcessor

 

Or parameter validation: BeanPostProcessor is also used

public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean

Part of the code is 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;
    }

Keywords: Java Spring xml

Added by phpknight on Sat, 10 Aug 2019 16:43:10 +0300