This is the 26th day of my participation in the August Text Challenge.More challenges in August
preface
Spring BeanFactoryPostProcessor interface invokeBeanFactoryPostProcessors method is mainly used for processing, RegisterBeanPostProcessors method is mainly used for processing the BeanPostProcessor interface.
BeanFactoryPostProcessor differs from BeanPostProcessor:
- BeanFactoryPostProcessor is an extension to BeanFactory. It is used to read the bean definition and modify it before it is instantiated.
- BeanPostProcessor BeanPostProcessor is an extension to beans that is used after bean instantiation and before and after initialization methods.
For example, AOP’s ability to generate proxies is to generate proxy objects after being instantiated by proxy classes.
Spring source code analysis series
- Spring source code analysis – source code reading environment construction
- Spring source Code analysis -IOC basic concepts
- Spring source code analysis -IOC core components
- Spring Source Code Analysis -IOC source code Analysis (1)
- Spring IOC source code analysis -obtainFreshBeanFactory
- Spring IOC source analysis – invokeBeanFactoryPostProcessors (3)
Source code analysis
RegisterBeanPostProcessors registers all the BeanPostProcessor, all achieved BeanPostProcessor class loading into the BeanFactory.
The BeanPostProcessor interface is an extension point exposed when Spring initializes beans. The Spring IoC container allows the BeanPostProcessor to add its own logical processing before and after the container initializes beans. In just register to the BeanFactory registerBeanPostProcessors method, the specific call is in bean initialization time.
registerBeanPostProcessors
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1. Find all classes that implement the BeanPostProcessor interface
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true.false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
/ / BeanPostProcessor counting
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 2. Add BeanPostProcessorChecker, which records information to BeanFactory
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 3. Define different variables to distinguish between the BeanPostProcessor of the PriorityOrdered, Ordered interface and the common BeanPostProcessor
/ / 3.1 priorityOrderedPostProcessors storage implementation PriorityOrdered BeanPostProcessor interface
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 3.2 internalPostProcessors stores Spring's internal BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
/ / 3.3 orderedPostProcessorNames storage realize Ordered BeanPostProcessor interface Name
List<String> orderedPostProcessorNames = new ArrayList<>();
3.4 Store the BeanName of the common BeanPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 4. Iterate through postProcessorNames
for (String ppName : postProcessorNames) {
// 4.1 Implement BeanPostProcessor processing for PriorityOrdered interfaces
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
/ / 4.2 if pp corresponding Bean instance also implements the MergedBeanDefinitionPostProcessor interface, is added to the internalPostProcessors
if (pp instanceofMergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
/ / 4.3 implements Ordered interface, added to the orderedPostProcessorNames
orderedPostProcessorNames.add(ppName);
}
else {
/ / 4.4 ordinary nonOrderedPostProcessorNamesnonOrderedPostProcessorNames.add(ppName); }}// First, register the BeanPostProcessors that implement PriorityOrdered.
// 5. First, register BeanPostProcessors implementing the PriorityOrdered interface
/ / 5.1 sorting
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
/ / 5.2 registerBeanPostProcessors registration
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 6. Next, register BeanPostProcessors implementing Ordered interface
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
// 6.1 Get the BeanPostProcessor corresponding to ppName
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
// add to orderedPostProcessors ready to perform registration
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
/ / 6.3 if pp instance realized MergedBeanDefinitionPostProcessor interface, also added to the internalPostProcessorsinternalPostProcessors.add(pp); }}/ / 6.4 sorting
sortPostProcessors(orderedPostProcessors, beanFactory);
// add orderedPostProcessors
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
// 7. Register normal BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// finally, re-register internalPostProcessors, (equivalent to moving to the end of the list)
/ / 8.1 sorting
sortPostProcessors(internalPostProcessors, beanFactory);
// 8.2 Register internalPostProcessors
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
/ / 9. Register ApplicationListenerDetector, main purpose is to move to the end of the processing chain
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
Copy the code
priorityOrderedPostProcessors
I’m not going to talk about this one
registerBeanPostProcessors
/** * Register the given BeanPostProcessor beans. */
private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List
postProcessors)
{
for(BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); }}Copy the code
beanFactory#addBeanPostProcessor
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
// If it exists, remove it
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
/ / set the logo hasInstantiationAwareBeanPostProcessors
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
/ / set the logo hasDestructionAwareBeanPostProcessors
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
// Add beanPostProcessor to the list
this.beanPostProcessors.add(beanPostProcessor);
}
Copy the code
To expand case
Define MyBeanPostProcessor to implement the BeanPostProcessor interface
public class MyBeanPostProcessor implements BeanPostProcessor.PriorityOrdered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Before Bean instantiation... " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("After Bean instantiation..." + beanName);
return bean;
}
@Override
public int getOrder(a) {
return 0; }}Copy the code
Define the User object and define the Bean through Configuration
/ / the User object
public class User {
private String name;
public User(a) {
System.out.println("User object instantiation");
}
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name; }}/ / define the Bean
@Configuration
public class BeanConfig {
@Bean
public User user(a) {
return new User();
}
@Bean
public MyPostProcessorBean myPostProcessorBean(a) {
return newMyPostProcessorBean(); }}Copy the code
Unit testing
public class BeanPostProcessorTest {
@Test
public void test(a) {
ApplicationContext context =
newAnnotationConfigApplicationContext(BeanConfig.class); }}Copy the code
The results of
Watch out for two easy holes
- BeanPostProcessor depends on beans that do not execute BeanPostProcessor’s methods
- The BeanPostProcessor and its dependent beans cannot use AOP
The last
In this way, there are too many Spring concepts, so we need to sort out the differences between these points and draw more pictures.