Spring 5.x Source trip thirty-six getBean point two extension Processor

Figure no less

Here Insert Picture Description

Examples provider obtainFromSupplier

Can make their own provider provides examples of direct return.

Here Insert Picture Description
Here Insert Picture Description

Real

We want to clean this class is registered to the container:

public class MySupplier implements Supplier {
    @Override
    public Object get() {
        MyBeforeInstantiation instantiation=new MyBeforeInstantiation();
        instantiation.age=100;
        return instantiation;
    }
}

Examples provider MySupplier

public class MySupplier implements Supplier {
    @Override
    public Object get() {
        return new MyBeforeInstantiation();
    }
}

Test code

Test code:

    @Test
    public void MySupplierTest() throws Exception {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(MyConfig.class);
        applicationContext.registerBean("myBeforeInstantiation",MyBeforeInstantiation.class,new MySupplier());
        applicationContext.refresh();
        MyBeforeInstantiation myBeforeInstantiation = applicationContext.getBean(MyBeforeInstantiation.class);
        System.out.println(myBeforeInstantiation.age);

    }

Here Insert Picture Description

SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors

createBeanInstanceThe determineConstructorsFromBeanPostProcessorsacquisition constructor. This is mainly AutowiredAnnotationBeanPostProcessormay help you pick out Autowiredthe annotated method. But we own extension a try.

Here Insert Picture Description
As long as there returned constructor is not empty, then return directly.
Here Insert Picture Description

Real

There are two methods of construction time, AutowiredAnnotationBeanPostProcessorwe will select the default constructor, so the output should be 0. But this time I want him to use the second constructor.

MyBeforeInstantiation

MyBeforeInstantiationWe want to instantiate the class:

@Component
public class MyBeforeInstantiation {
    public int age;

    public MyBeforeInstantiation(){
        System.out.println("MyBeforeInstantiation()");
    }

    public MyBeforeInstantiation(PoJo poJo1,PoJo poJo2) {
        System.out.println("BeforeInstantiation(PoJo poJo1,PoJo poJo2)");
    }

}

//测试用的
@Component
public class PoJo {
}

Test code

 @Test
    public void determineCandidateConstructorsTest() throws Exception {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(MyConfig.class);
        applicationContext.refresh();

    }

Output results:
Here Insert Picture Description

MySmartInstantiationAwareBeanPostProcessor extension Processor

I specify that he returned the second constructor.

@Component
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {
    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        if(beanClass.getSimpleName().equals(MyBeforeInstantiation.class.getSimpleName())){
            try {
                return new Constructor[]{beanClass.getDeclaredConstructor(PoJo.class,PoJo.class)};
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

Results:
Here Insert Picture Description
We successfully changed the original setting.

doubt

But there is a problem, there is thought, is why our processors within the processor AutowiredAnnotationBeanPostProcessorprior to the treatment, we did not declare any prioritization ah, in fact, this is registered processors registerBeanPostProcessorswill be the MergedBeanDefinitionPostProcessortype of put internalPostProcessorsin, while AutowiredAnnotationBeanPostProcessorand CommonAnnotationBeanPostProcessorexactly this type, they finally registered again, and the method of registration will be deleted exists, then put the newly registered last.
Here Insert Picture Description
Here Insert Picture Description
This explains why we are in front of them, they would have to register go, only the last is re-registered to the back, so the processor can execute our first return to the constructor is not nulldirectly return the objects.

Of course, if you implement in order to guarantee the order, then PriorityOrderedthe interface it, such as there are other processor, and must have a right order:

@Component
public class MySmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, PriorityOrdered {
    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        if(beanClass.getSimpleName().equals(MyBeforeInstantiation.class.getSimpleName())){
            try {
                return new Constructor[]{beanClass.getDeclaredConstructor(PoJo.class,PoJo.class)};
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

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

Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.

Published 235 original articles · won praise 74 · views 30000 +

Guess you like

Origin blog.csdn.net/wangwei19871103/article/details/105168234