Other extensions can be found in previous articles:

1. In-depth understanding of The Spring IOC extension (1), Custom XML tags

2. In-depth understanding of Spring IOC extension ii, BeanFactoryPostProcessor, and BeanPostProcessor

This paper mainly introduces three initialization, respectively is @ PostConstruct, InitializingBean, and SmartInitializingSingleton these three, we directly three function, take a look at the code.

@Component
public class TestP implements InitializingBean.SmartInitializingSingleton {

    @PostConstruct
    public void test() {
        System.out.println("@PostConstruct");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // InitializingBean method
        System.out.println("afterPropertiesSet");
    }

    @Override
    public void afterSingletonsInstantiated() {
        / / SmartInitializingSingleton method
        System.out.println("afterSingletonsInstantiated"); }}Copy the code

The code is simple. Let’s see what happens when the container is started:

We can see that three kinds of way to initialize the corresponding business logic has been carried out, and we can observe that @ PostConstruct were the first to be performed, then the InitializingBean, finally is SmartInitializingSingleton, So what are the specific differences? Let’s go to the source code to have a look.

Calls the initialization code in the initializeBean AbstractAutowireCapableBeanFactory method

        protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		// Invoke several Aware interfaces
		if(System.getSecurityManager() ! =null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
		
		/ / call all the BeanPostProcessor postProcessBeforeInitialization
		Object wrappedBean = bean;
		if (mbd == null| |! mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }try {
			// Call the InitializingBean methods and custom initialization methods
			invokeInitMethods(beanName, wrappedBean, mbd);
		}catch (Throwable ex) {
			throw newBeanCreationException( (mbd ! =null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}

		/ / perform all BeanPostProcessor postProcessAfterInitialization method
		if (mbd == null| |! mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }return wrappedBean;
	}
Copy the code

In this method, we can clearly see where InitializingBean is executed. Where is @PostConstruct executed? After debug, we can find it at the time of calling all BeanPostProcessor postProcessBeforeInitialization execution (CommonAnnotationBeanPostProcessor). SmartInitializingSingleton this thing need to say first, then Spring4.0 when there is no this thing, this is added after 4.1, this can also be used to do some operation after initialization, so what time is it implemented? We can be found in the last few lines in the preInstantiateSingletons DefaultListableBeanFactory:

At this point, all beans have already been initialized. So we are here to do a small summary: the three initialization, the method of execution order is @ PostConstruct, then the InitializingBean, finally is SmartInitializingSingleton. For use on A small example, if A bean will rely on B bean initialization data, you can make A to realize SmartInitializingSingleton, B to realize InitializingBean or use @ PostConstruct, The way InitializingBean and @PostConstruct are initialized is no different in most cases. It is also important to note that these three initialization methods should not be used in conjunction with BeanFactoryPostProcessor and BeanPostProcessor, because they are things that are done at different stages of the container. For example:

@Component
public class AProcessor implements BeanPostProcessor.PriorityOrdered {

    @PostConstruct
    public void test() {
        System.out.println("AProcessor @PostConstruct");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("aa");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("bb");
        return null;
    }

    @Override
    public int getOrder() {
        return 0; }}Copy the code

So this class implements the BeanPostProcessor and PriorityOrdered interfaces, and then when we start it up we find that something inside @Postconstruct is not being executed, The reason for this is that the BeanPostProcessor used to execute @postconstruct was not initialized at the time of its initialization, so of course it can’t be executed. This is just a random one I thought of, and there may be other ones, so use them separately as much as possible.

Writing an article is not easy, especially finished to make a summary of a huge thing is not easy, so your praise is very important to me, ask for a praise 🥺 ~