Post processor analysis of IOC container beanfactoryprocessor

Help me to the Internet cafe 2022-05-14 14:40:00 阅读数:769

postprocessoranalysisioccontainer

Preface

Last article Spring Ioc Source analysis series --Ioc Source code entry analysis Already introduced Ioc The inlet of the container refresh() Method , And analyzed refresh() The first three sub methods in the method are analyzed . Remember what you analyzed ? I guess I forgot what I analyzed , It can be said that I saw a lonely . But don't panic , It must be normal to read and forget , Need to review , You'd better take some notes , Only when you have your own precipitation will you be impressed . You'd better follow the code and debug it yourself several times , It's on paper , We must know that we must do it .

Okay , Here's a review of the last article . The last article mainly analyzed three methods ,prepareRefresh() Set some properties before starting the container ,obtainFreshBeanFactory() Method completes reading the configuration file , The implementation of this method will be aimed at xml Configure and create internal containers , This container is responsible for bean Creation and management of , Will be carried out in BeanDefinition Registration of ,prepareBeanFactory(beanFactory) This method mainly registers some systems that need to be used in the container bean, for example classloader,BeanFactoryPostProcessor etc. .

After drinking chicken soup and looking back , The following is the beginning of the main body of today's article .

Think about a problem ,Spring Provides very good scalability , So where is scalability reflected ? Different people have different opinions on this issue , But compress the scene , Compressed to the previous article, we have obtained a loading completion BeanDefinition On the container , I'm in a unified BeanDefinition After loading , I want to modify one or add one BeanDefinition, How to achieve it at this time ?

Yes Spring Familiar readers may have guessed , It can be used at this time BeanFactoryPostProcessor The post processor completes this operation , Then this article will solve two questions :

  • BeanFactoryPostProcessor What is it and how to use it ?
  • BeanFactoryPostProcessor The calling logic in the source code ?

The first question will be illustrated by an example , The second question will be explained through source code analysis . Don't talk nonsense , to BeanFactoryPostProcessor Introduce , Then use the example of the previous article to realize BeanFactoryPostProcessor To replace UserService The implementation of the .

BeanFactoryPostProcessor Introduce

This is a container hook method , Allows you to customize and modify the context of your application  bean  Definition , Adjust the context  bean  Factory  bean  Property value . For users who want to overwrite the configuration in the application context with the custom configuration file of the system administrator  bean  Properties are very effective .BeanFactoryPostProcessor It can be done with  bean  Define interactions and modifications , But not with  bean  Instance interaction . Doing so may lead to premature  bean  Instantiation , Violate the container and cause unexpected side effects . if necessary bean Instance interaction , Please consider implementing  BeanPostProcessor.ApplicationContext  Automatically detect its  bean  In the definition  BeanFactoryPostProcessor , And create any other  bean  Apply them before . BeanFactoryPostProcessor  You can also register to... Programmatically  ConfigurableApplicationContext.

This class has only one method , The input parameter is the current container , So let's see postProcessBeanFactory() This method .

@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
*
* Modify the internal of the application context after standard initialization bean factory .
* all bean Definitions will be loaded , But not yet. bean Be instantiated .
* This allows you to override or add attributes , Even eager to initialize bean.
*
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

You can see that the operation space here is very large , Directly transfer the current container into , It means that you can do anything based on the current container . For example, you look at the goddess every day , It's impossible to be expected , But one day through a portal , Sent the goddess to your house , Can you do whatever you want , Do whatever you want , For example, you can let her wear the clothes you like , Eat what you like and so on .

Code example

Then let's implement it with code . In the last article Spring Ioc Source analysis series --Ioc Source code entry analysis Add code based on , All source code can be found in My warehouse ioc-sourcecode-analysis-code-demo Found in .

First, create a new one ReplaceUserServiceImpl Class implementation UserService.

/**
* @author Codegitz
* @date 2022/5/12 15:57
**/
public class ReplaceUserServiceImpl implements UserService {
@Override
public User getUser(String name, String age) {
User user = new User();
user.setId("1");
// The assignment is changed here
user.setName("ReplaceUser-" + name);
user.setAge(age);
return user;
}
}

Then use a class to implement BeanFactoryPostProcessor. You can see that my logic here is also very simple , Is to judge whether there is a named userService Of BeanDefinition, If so, replace its implementation with io.codegitz.service.impl.ReplaceUserServiceImpl.

/**
* @author Codegitz
* @date 2022/5/12 16:01
**/
public class ReplaceUserBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (beanFactory.containsBeanDefinition("userService")){
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
beanDefinition.setBeanClassName("io.codegitz.service.impl.ReplaceUserServiceImpl");
}
}
}

The post processor is ready , Next, register the post processor in the container , My code example uses xml The way .

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="io.codegitz.service.impl.UserServiceImpl"/>
<!-- Register the post processor -->
<bean id="processor" class="io.codegitz.processor.ReplaceUserBeanFactoryPostProcessor"/>
</beans>

It's all done here , Then you can start the boot class to run and see the effect . You can see that the implementation here has been replaced by ReplaceUserServiceImpl, Explain our ReplaceUserBeanFactoryPostProcessor The post processor is working , So how did it take effect ? Enter the source code analysis in the next section .

Source code analysis

The above function has been realized through an example , So how is it implemented in the source code ? Here will be connected with the source code analysis of the previous article , Continue to refresh() Wandering in the method . The previous article has analyzed the first three , This article will continue to analyze two methods , Namely postProcessBeanFactory(beanFactory)  and invokeBeanFactoryPostProcessors(beanFactory),invokeBeanFactoryPostProcessors(beanFactory) Is the logic of the post processor , Link up the above example . good heavens , Connect with each other .

postProcessBeanFactory(beanFactory)

This is an empty method , It's left for subclasses to implement , Mainly a few web dependent ApplicationContext Will rewrite this method , The current container is passed in , The operating space is also very large . Because it's an empty method , No more details here .

 /**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
*
* Modify the internal of the application context after standard initialization bean factory .
* all bean The definitions have been loaded , But not yet. bean Be instantiated .
* This allows for some ApplicationContext Register special in the implementation BeanPostProcessors etc. .
*
* @param beanFactory the bean factory used by the application context
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

invokeBeanFactoryPostProcessors(beanFactory)

Then we enter today's play , Follow up the code , You can see that the main code implementation is delegated to PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()) To achieve .

 /**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*
* Instantiate and call all registered BeanFactoryPostProcessor bean, If the order is given , Then execute in order
* All post processors must be in other singletons bean Called before instantiation
*/
// Instantiate and call all BeanFactoryPostProcessor beans
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// This method performs two operations
// 1. Put the given BeanFactoryPostProcessor Incoming execution
// 2. Automatically scan all the... In the container BeanFactoryPostProcessor perform
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
// Detect whether there is temporary for type matching ClassLoader and LoadTimeWeaver
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

To follow up PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()) Code inside . This method is longer , But the logic is very simple , Follow the notes. It's not a big problem to understand .

 public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// The conventional BeanFactoryPostProcessor Post Processors
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// Extended registration BeanDefinition Of BeanDefinitionRegistryPostProcessor Post Processors
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// Put it into different post processor lists according to the type
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// There is no initialization here FactoryBeans, Because if you initialize first BeanFactoryPostProcessor You can't do the initialization for bean It works
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// First, we will call the implementation PriorityOrdered Interface BeanDefinitionRegistryPostProcessors
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// Next, the call implements Ordered Interface BeanDefinitionRegistryPostProcessors
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// Last , Call... That does not implement the above interface BeanDefinitionRegistryPostProcessors
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
// Why should we put... Here again reiterate Set to true?
// Because here BeanDefinitionRegistryPostProcessor May register another BeanFactoryPostProcessor,
// So you need a loop to iterate , Until now, there is no... In the container BeanFactoryPostProcessor until
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// Registration may continue here BeanFactoryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// The previous processing has completed all BeanDefinitionRegistryPostProcessor,
// The next two methods are to deal with BeanFactoryPostProcessor,
// Note that this only deals with the method passed in beanFactoryPostProcessors ,
// After processing this, the subsequent logic will automatically detect all... In the current container BeanFactoryPostProcessor, Then call... One by one
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
// If given beanFactory No BeanDefinitionRegistry,
// Then you don't need to make the previous call BeanDefinitionRegistryPostProcessor The operation of ,
// Directly call the given beanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// The logic here is the same as that above BeanDefinitionRegistryPostProcessor The processing logic is similar
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// Classify according to different priorities BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// If the first stage has been handled , No longer handle
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// First of all, the implementation is called PriorityOrdered Interface BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// Secondly, the call implements Ordered Interface BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// Finally, call the... That does not implement the above interface BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// Clear cached merged bean definitions Definition , Because the postprocessor may have modified the original metadata , For example, replace a placeholder in a value ...
beanFactory.clearMetadataCache();
}

This method mainly does the following things :

  • First, we will judge whether the type of the current container is BeanDefinitionRegistry type , If it is , Then judge A given beanFactoryPostProcessors Whether there is BeanDefinitionRegistryPostProcessor Type of postprocessor , If so, execute postProcessBeanDefinitionRegistry() Method , Conduct BeanDefinition Registration of . Then, we will get the implementation of... In the current container respectively PriorityOrderedOrdered Interface and those that do not implement the sorting interface BeanDefinitionRegistryPostProcessor, After sorting, execute .
  • If not BeanDefinitionRegistry type , Call directly invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory) Method calls all the given BeanFactoryPostProcessor.
  • Go through the first two steps , The given... Has been processed beanFactoryPostProcessors, Here we will detect the existing in the execution container BeanFactoryPostProcessor. Here will also follow PriorityOrdered and Ordered Interface and the order in which the sorting interface is not implemented .
  • Finally, the configuration cache of metadata in the container will be emptied

The logic of this method is relatively simple , That is, the amount of code is relatively large , It takes patience to read .

Next, let's look at the contents of some word methods

sortPostProcessors() Finish post processor sorting

 private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
// Relatively simple , Is to get a comparator Comparator , as for Comparator Principle , You can read the relevant articles by yourself
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
comparatorToUse = OrderComparator.INSTANCE;
}
// Sort
postProcessors.sort(comparatorToUse);
}

invokeBeanDefinitionRegistryPostProcessors() Call all BeanDefinitionRegistryPostProcessor

This method is also relatively simple , Is to call one by one BeanDefinitionRegistryPostProcessor Post Processors .

 /**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
* Call the given BeanDefinitionRegistryPostProcessor bean.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}

invokeBeanFactoryPostProcessors() Call all BeanFactoryPostProcessor

Call one by one BeanFactoryPostProcessor Post Processors .

 /**
* Invoke the given BeanFactoryPostProcessor beans.
* Call the given BeanFactoryPostProcessor bean.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}

beanFactory.getBeanNamesForType() Get... By type bean name

beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false) It will get all the information of this type according to the type passed in bean name .

Follow up code view , Would call doGetBeanNamesForType() Method to get .

 public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
// The configuration is not frozen || The type is empty || Early initialization is not allowed entering
if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
}
Map<Class<?>, String[]> cache =
(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
String[] resolvedBeanNames = cache.get(type);
if (resolvedBeanNames != null) {
return resolvedBeanNames;
}
// Allow early initialization
resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
cache.put(type, resolvedBeanNames);
}
return resolvedBeanNames;
}

To follow up doGetBeanNamesForType() Method , This method is also relatively long , But the logic is also relatively clear , Just traverse beanDefinitionNames Judge whether it meets the type requirements , If yes, return .

 private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>();
// Check all bean definitions.
// From all of beanDefinitionNames Check all that meet the type requirements bean , Join in result
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
// If bean Name is not defined as other bean Another name for , Then bean Meet the requirements .
if (!isAlias(beanName)) {
try {
// obtain beanName Of RootBeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
// Whether the type matches
boolean matchFound = false;
boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
// The main thing is to call isTypeMatch() Method to determine whether the types match
if (!isFactoryBean) {
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
else {
if (includeNonSingletons || isNonLazyDecorated ||
(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
// If it matches, add
if (matchFound) {
result.add(beanName);
}
}
}
catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
// Omit some exception handling ..
}
}
}
// Check manually registered singletons too.
// Check the manually registered singleton bean
for (String beanName : this.manualSingletonNames) {
try {
// In case of FactoryBean, match object created by FactoryBean.
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// In case of FactoryBean, try to match FactoryBean itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
// If it matches, add
if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Omit some exceptions ...
}
}
return StringUtils.toStringArray(result);
}

Come here BeanFactoryPostProcessor The source code call and related logic analysis are finished , Is it simpler .

Summary

This article mainly introduces BeanFactoryPostProcessor Use of post processor and underlying principle . The beginning of the article first reviews the content of the previous article , Then example driven analysis , First, a simple example is used to realize BeanFactoryPostProcessor Use , Then the source code is analyzed , The idea of the whole article is relatively clear . So see here , Have you solved the first two questions of the article ?

  • BeanFactoryPostProcessor What is it and how to use it ?
  • BeanFactoryPostProcessor The calling logic in the source code ?

 

版权声明:本文为[Help me to the Internet cafe]所创,转载请带上原文链接,感谢。 https://javamana.com/2022/134/202205141436333128.html