1, BeanDefinitionRegistryPostProcessor class
/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans.factory.support; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; /** * Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for * the registration of further bean definitions <i>before</i> regular * BeanFactoryPostProcessor detection kicks in. In particular, * BeanDefinitionRegistryPostProcessor may register further bean definitions * which in turn define BeanFactoryPostProcessor instances. * * @author Juergen Hoeller * @since 3.0.1 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor */ public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }
Let's translate its notes.
Extension to the standard BeanFactoryPostProcessor SPI, allowing for the registration of further bean definitions before regular BeanFactoryPostProcessor detection kicks in. In particular, BeanDefinitionRegistryPostProcessor may register further bean definitions which in turn define BeanFactoryPostProcessor instances.
The extension to the standard beanfactorypostprocessor allows more bean definitions to be registered before the regular beanfactorypostprocessor detection starts. In particular, BeanDefinitionRegistryPostProcessor can register more bean definitions, which in turn define beanfactorypostprocessor instances.
From the source code, we can see that BeanDefinitionRegistryPostProcessor inherits the beanfactorypostprocessor class, which is an extension of it. The beanfactorypostprocessor class will be explained later.
Let's look at the methods defined by the interface:
Modify the application context's internal bean definition registry after its standard initialization. All regular bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for adding further bean definitions before the next post-processing phase kicks in.
Params:
registry – the bean definition registry used by the application context
Modify the internal bean definition registry of the application context after standard initialization. All regular bean definitions will be loaded, but no beans have been instantiated. This allows you to add more bean definitions before the next post-processing phase begins.
Let's explain here: standardized initialization is understood as spring parsing xml and scan classes, forming BeanDefiniton objects, and registering them in BeanFactory.
The execution trigger time of this interface is executed before BeanDefinition is registered with BeanFactory and instantiated.
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
The parameter of the method is BeanDefinitionRegistry. As we mentioned earlier, BeanDefinitionRegistry is used to register BeanDefinition with BeanFactory. This means that before the registration, this method is called to add and delete the BenDefiniton objects in the register.
To add, delete, modify and query beandefinition, we need to customize the class, implement the BeanDefinitionRegistryPostProcessor interface, and then implement the method to add, delete, modify and query beandefinition.
The class that implements the BeanDefinitionRegistryPostProcessor interface needs to be decorated with @ Component and added to the spring container before it can be resolved by spring. As mentioned above, the way to execute the interface is before instantiating the object. However, to execute the methods of the interface implementation class, you must instantiate the implementation class of the interface. Therefore, the instantiation process of BeanDefinitionRegistryPostProcessor implementation class is instantiated before executing the postProcessBeanDefinitionRegistry method. The instantiation of this implementation class is the earliest.
The parameter BeanDefinitionRegistry of the postProcessBeanDefinitionRegistry method is passed in by spring itself during initialization. We don't need to care where this object comes from. We can use it directly in the method. We must understand this principle. When implementing some interfaces, the interface parameters provide us with some framework level classes as parameters for us to call. Then this parameter must be an object maintained by the framework during operation. We just need to take the properties in the object to apply.
2, Beanfactoryprocessor class
/* * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; /** * Factory hook that allows for custom modification of an application context's * bean definitions, adapting the bean property values of the context's underlying * bean factory. * * <p>Useful for custom config files targeted at system administrators that * override bean properties configured in the application context. See * {@link PropertyResourceConfigurer} and its concrete implementations for * out-of-the-box solutions that address such configuration needs. * * <p>A {@code BeanFactoryPostProcessor} may interact with and modify bean * definitions, but never bean instances. Doing so may cause premature bean * instantiation, violating the container and causing unintended side-effects. * If bean instance interaction is required, consider implementing * {@link BeanPostProcessor} instead. * * <h3>Registration</h3> * <p>An {@code ApplicationContext} auto-detects {@code BeanFactoryPostProcessor} * beans in its bean definitions and applies them before any other beans get created. * A {@code BeanFactoryPostProcessor} may also be registered programmatically * with a {@code ConfigurableApplicationContext}. * * <h3>Ordering</h3> * <p>{@code BeanFactoryPostProcessor} beans that are autodetected in an * {@code ApplicationContext} will be ordered according to * {@link org.springframework.core.PriorityOrdered} and * {@link org.springframework.core.Ordered} semantics. In contrast, * {@code BeanFactoryPostProcessor} beans that are registered programmatically * with a {@code ConfigurableApplicationContext} will be applied in the order of * registration; any ordering semantics expressed through implementing the * {@code PriorityOrdered} or {@code Ordered} interface will be ignored for * programmatically registered post-processors. Furthermore, the * {@link org.springframework.core.annotation.Order @Order} annotation is not * taken into account for {@code BeanFactoryPostProcessor} beans. * * @author Juergen Hoeller * @author Sam Brannen * @since 06.07.2003 * @see BeanPostProcessor * @see PropertyResourceConfigurer */ @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. * @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; }
Translate its notes:
Factory hook that allows for custom modification of an application context's bean definitions, adapting the bean property values of the context's underlying bean factory.
The factory hook allows the client to modify the beandefinition object initialized by spring and adjust the attribute value of the bean.
Useful for custom config files targeted at system administrators that override bean properties configured in the application context. See PropertyResourceConfigurer and its concrete implementations for out-of-the-box solutions that address such configuration needs.
It is useful for custom configuration files for system administrators that override the bean properties configured in the application context. See propertyresourceconfigurator and its implementation for an out of the box solution that meets these configuration requirements.
Check the propertyresourceconfigurator later. Continue to read its notes:
A BeanFactoryPostProcessor may interact with and modify bean definitions, but never bean instances. Doing so may cause premature bean instantiation, violating the container and causing unintended side-effects. If bean instance interaction is required, consider implementing BeanPostProcessor instead.
Beanfactoryprocessor can interact and modify with beandefinition, but cannot interact with bean instances. Doing so may cause the bean to instantiate prematurely, violate the container, and cause unexpected side effects. If you need bean instance interaction, consider implementing BeaPASTePrimor.
This sentence means that the beanfactoryprocessor interface can modify the BeanDefinition object instead of the bean instance. If you want to interact with an instance of a bean, use BeaPASTePrimor. What is BeaPASTePrimor? Let's talk about it later. Continue to read the notes:
An ApplicationContext auto-detects BeanFactoryPostProcessor beans in its bean definitions and applies them before any other beans get created. A BeanFactoryPostProcessor may also be registered programmatically with a ConfigurableApplicationContext.
ApplicationContext automatically detects beanfactoryprocessor beans in its beandefinition and applies them before creating any other beans. Beanfactoryprocessor can also be registered programmatically with ConfigurableApplicationContext.
How to register with ConfigurableApplicationContext? Let's talk about it later and continue to look at the notes:
BeanFactoryPostProcessor beans that are autodetected in an ApplicationContext will be ordered according to org.springframework.core.PriorityOrdered and org.springframework.core.Ordered semantics. In contrast, BeanFactoryPostProcessor beans that are registered programmatically with a ConfigurableApplicationContext will be applied in the order of registration; any ordering semantics expressed through implementing the PriorityOrdered or Ordered interface will be ignored for programmatically registered post-processors. Furthermore, the @Order annotation is not taken into account for BeanFactoryPostProcessor beans.
The beanfactoryprocessor bean automatically detected in the application context will be generated according to org springframework. core. PriorityOrdered and org springframework. core. Ordered semantics. On the contrary, the BeanFactoryPostProcessor bean programmed and registered with ConfigurableApplicationContext will be applied in the Order of registration; For post processors registered programmatically, any sort semantics expressed by implementing the PriorityOrdered or ordered interface will be ignored. In addition, the BeanFactoryPostProcessor bean does not consider the @ Order annotation.
See interface methods and notes below:
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 bean factory of the application context after standard initialization. All bean definitions will be loaded, but no beans have been instantiated. This allows you to override or add properties, even for beans.
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
It can be seen that the parameter of the method is ConfigurableListableBeanFactory, which is a modification of BeanDefinition in beanFactory.
Now, let's compare the beanfactory postprocessor interface with the BeanDefinitionRegistryPostProcessor interface. The parameter in beanfactoryprocessor method is ConfigurableListableBeanFactory. Let's see which methods this object has:
As you can see, this method mainly obtains the BeanDefiniton object, and then modifies the attribute value of BeanDefiniton.
The method parameter of BeanDefinitionRegistryPostProcessor interface is BeanDefinitionRegistry object, and its methods include;
It can be seen that this method is mainly to add or remove BeanDefinition, or obtain BeanDefiniton and modify its properties. Therefore, this method is mainly used to add, delete, modify and query BeanDefiniton. In fact, to a certain extent, the functions of BeanDefinitionRegistryPostProcessor include the functions of its parent interface beanfactoryprocessor.
The execution order of the two interface methods is to execute BeanDefinitionRegistryPostProcessor first, and then beanfactorypost processor. We can also know from the parameter type that we must register BeanDefinition first, and then operate beanfactory after BeanDefinition is registered with beanfactory.