Spring 5.x Source trip thirty-six getBean point two extension Processor
Figure no less
Examples provider obtainFromSupplier
Can make their own provider provides examples of direct return.
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);
}
SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors
createBeanInstance
The determineConstructorsFromBeanPostProcessors
acquisition constructor. This is mainly AutowiredAnnotationBeanPostProcessor
may help you pick out Autowired
the annotated method. But we own extension a try.
As long as there returned constructor is not empty, then return directly.
Real
There are two methods of construction time, AutowiredAnnotationBeanPostProcessor
we will select the default constructor, so the output should be 0
. But this time I want him to use the second constructor.
MyBeforeInstantiation
MyBeforeInstantiation
We 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:
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:
We successfully changed the original setting.
doubt
But there is a problem, there is thought, is why our processors within the processor AutowiredAnnotationBeanPostProcessor
prior to the treatment, we did not declare any prioritization ah, in fact, this is registered processors registerBeanPostProcessors
will be the MergedBeanDefinitionPostProcessor
type of put internalPostProcessors
in, while AutowiredAnnotationBeanPostProcessor
and CommonAnnotationBeanPostProcessor
exactly this type, they finally registered again, and the method of registration will be deleted exists, then put the newly registered last.
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 null
directly return the objects.
Of course, if you implement in order to guarantee the order, then PriorityOrdered
the 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.