当前位置:网站首页>Differences between beanfactorypostprocessor and beanpostprocessor
Differences between beanfactorypostprocessor and beanpostprocessor
2022-06-11 10:11:00 【Yu 1990】
Original address :https://www.cnblogs.com/dreampig/p/9036077.html
original text :https://www.jianshu.com/p/fb39f568cd5e
1、 brief introduction
BeanPostProcessor and BeanFactoryProcessor yes Spring There are two important interfaces in . Let's take a look first Spring In your document BeanPostProcessor The definition of :
The BeanPostProcessor interface defines callback methods that you can
implement to provide your own (or override the container’s default)
instantiation logic, dependency-resolution logic, and so forth. If you want
to implement some custom logic after the Spring container finishes
instantiating, configuring,and initializing a bean, you can plug in one or
more BeanPostProcessor implementations.
BeanPostProcessor Interface defines a callback method that you can implement yourself , To implement your own instantiation logic 、 Dependency resolution logic, etc , If you want to be in Spring Complete object instantiation 、 To configure 、 Implement your own business logic after initialization , You can complement one or more BeanPostProcessor The implementation of the .
Let's take a look at the document BeanFactoryPostProcessor Description of :
The semantics of this interface are similar to those of the
BeanPostProcessor, with one major difference:BeanFactoryPostProcessor
operates on the bean configuration metadata; that is, the Spring IoC
container allows a BeanFactoryPostProcessor to read the configuration
metadata and potentially change it before the container instantiates any
beans other than BeanFactoryPostProcessors.
BeanFactoryPostProcessor The definition and BeanPostProcessor be similar , One of the main differences is :BeanFactoryPostProcessor It can be done to bean The configuration information of ; More precisely Spring IOC Container allowed BeanFactoryPostProcessor Read configuration information and be able to instantiate any other... In the container bean( It's all done BeanFactoryPostProcessor The class of the interface ) Change the configuration information before
2、BeanPostProcessor and BeanFactoryProcessor The definition of
BeanPostProcessor There are two ways :
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* @param bean bean Example
* @param beanName bean Of name
* @return Return the processed bean, It can be the original Bean Or after packaging Bean;
* If you return null, Follow up BeanPostProcessor Will not be executed
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* @param bean bean Example
* @param beanName bean Of name
* @return Return the processed bean, It can be the original Bean Or after packaging Bean;
* If you return null, Follow up BeanPostProcessor Will not be executed
* {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
We can see the comments postProcessBeforeInitialization The way is in all bean Of InitializingBean Of afterPropertiesSet Method is executed before postProcessAfterInitialization The method is in all bean Of InitializingBean Of afterPropertiesSet Method followed by .
and BeanFactoryPOSTProcessor There is only one way :
*/
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;
}
We can see in the comments that :postProcessBeanFactory Can be in BeanFactory Modify the inside of the container after instantiation BeanFactory. At this time, all the bean Have been loaded , But no bean Initialized . This allows BeanFactoryPOSTProcessor Rewrite or add configuration , You can even initialize in advance bean.
Okay , Said so much , Maybe everyone is right BeanPostProcessor and BeanFactoryProcessor Still a little confused , Let's take a look at an example to understand :
3、 Example
Let's create a class implementation first BeanPostProcessor:
public class TestBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "-->" + "TestBeanPostProcessor->postProcessBeforeInitialization");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "-->" + "TestBeanPostProcessor->postProcessAfterInitialization");
return bean;
}
}
After creating a class implementation BeanFactoryPostProcessor:
public class TestBeanFactoryPostPorcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("TestBeanFactoryPostPorcessor->postProcessBeanFactory");
}
}
And then create a normal bean, Realized InitializingBean and DisposableBean Interface :
public class TestBean implements InitializingBean, DisposableBean{
private String name;
private int age;
public TestBean() {
System.out.println("TestBean->constrcutor");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("TestBean->setter");
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("TestBean->setter");
this.age = age;
}
public void destroy() throws Exception {
System.out.println("TestBean->destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("TestBean->afterPropertiesSet");
}
}
And then in xml Register these three... In the file bean:
<bean id="testBeanPostProcessor" class="wbx.test_spring_noweb.beans.TestBeanPostProcessor"></bean>
<bean id="testBeanFactoryPostProcessor" class="wbx.test_spring_noweb.beans.TestBeanFactoryPostPorcessor"></bean>
<bean id="testBean" class="wbx.test_spring_noweb.beans.TestBean">
<property name="name" value=" Ugly star "></property>
<property name="age" value="18"></property>
</bean>
Finally, write a test class to run :
public class Test {
public static void main(String[] args) {
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("classpath:wbx/test_spring_noweb/beans.xml");
TestBean testBean = (TestBean)context.getBean("testBean");
context.destroy();
}
}
We can see the running results of the console , Part of the screenshot here :

Test run results
We can see Bean Life cycle of :
1、 analysis xml file , It is concluded that BeanDefinition
2、Spring Container to create BeanFactoryPostProcessor example
3、 call BeanFactoryPostProcessor Of postProcessBeanFactory Method
4、Spring Container to create BeanPostProcessor example
5、 Create other... As needed Bean Create another instance Bean
6、 call Bean Construction method of
7、 call Bean Of setter Method is Bean Attribute assignment
8、 call BeanPostProcessor Of postProcessBeforeInitialization Method
9、 call InitializingBean Of afterPropertiesSet Method
10、 call BeanPostProcessor Of postProcessAfterInitialization Method
11、 Call when the container is destroyed DisposableBean Of destroy Method
4、BeanPostProcessor stay Spring Examples of internal use
We all know , When one Bean Realized OoXxAware After the interface ,Spring Will automatically send OoXx Object injection , for example : One Bean Realized ApplicationContextAware Interface ,Spring Will try to ApplicationContext Object injection into this Bean in , How can this be achieved ?
When Spring When the container is initialized , Will first parse Bean The definition of , Parse the definition into BeanDefinition object , And by the BeanDefinitionHolder Packaging layer , Sign up to BeanFactory in . Let's take a look at the container refresh method (AbstractApplicationContext Class ):
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
analysis Bean stay ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); Finish in . Interested students can have a look at . And then call postProcessBeanFactory(beanFactory); Method , Let's take a look at this method :
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
This method is actually for BeanFactory Initialize the values of some properties .
We can see that there is a line of code :beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
ApplicationContextAwareProcessor Realized BeanPostProcessor Interface . This line of code will ApplicationContextAwareProcessor Sign up to beanFactory Of BeanPostProcessor Collection . Let's take another look ApplicationContextAwareProcessor Part of the code :
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
ApplicationContextAwareProcessor Will judge first bean Is it implemented Aware Interface , If it is , According to Aware Type to call the corresponding defined interface to give Bean Inject corresponding resources .
5、 summary
BeanPostProcessor and BeanFactoryProcessor The difference is the key , It is often taken in the interview . What's more, a Ben Life cycle of , I hope you can focus on the examples in the third part , Understand well Bean Life cycle of !
Spring Two kinds of post-processing are provided bean Extension interface for , Respectively BeanPostProcessor and BeanFactoryPostProcessor, The two are different in use .
BeanPostProcessor:bean Level of processing , For a specific bean To deal with

The interface provides two methods , They are the pre initialization and post initialization execution methods , What is the specific initialization method , It's like we're defining bean when , Defined init-method The specified method <bean id = "xxx" class = "xxx" init-method = "init()">
These two methods are respectively in init Before and after the method , One thing to note , We define a class that implements BeanPostProcessor, The default is for the whole Spring Everything in the container bean To deal with .
Since it is all processed by default , So how do we confirm that we need to deal with a specific bean Well ?
You can see that there are two parameters in the method . The types are Object and String, The first parameter is each bean Example , The second parameter is each bean Of name perhaps id The value of the property . So we can use the second parameter , To confirm the specific bean.
The processing of this occurs in Spring After container instantiation and dependency injection .
BeanFactoryPostProcessor:BeanFactory Level of processing , It's about the whole Bean The factory of

This interface provides only one method , Method parameters are ConfigurableListableBeanFactory, Let's see what methods are defined in this class

One of the methods is called getBeanDefinition Methods , We can use this method , Find our definition bean Of BeanDefinition object . Then we can modify the defined properties , Here are BeanDefinition The method in


Have you found any methods with names similar to ours bean Attributes of the tag ,setBeanClassName Corresponding bean In the tag class attribute , So when we get BeanDefinition Object time , We can modify it manually bean Attribute values defined in the tag .
Specifically, this BeanDefinition What kind of object is it , When we're in xml It defines bean When labeling ,Spring They will bean The tag resolves into a javabean, This BeanDefinition Namely bean The label corresponds to javabean.
So when we call BeanFactoryPostProcess When the method is used , Now bean Not yet instantiated , here bean It's just been interpreted as BeanDefinition object .
Spring Container initialization bean General process Definition bean label > take bean The label resolves to BeanDefinition> Call constructor instantiation (IOC)> Attribute is worth dependency injection (DI)
therefore BeanFactoryPostProcess Method execution occurs after the second part , Before the third step .
summary : Both of the above are Spring Post treatment provided bean The interface of , It's just that the timing of implementation is different . The former is after instantiation , The latter is before instantiation . The function , The latter is right bean It's more powerful .
The above personal understanding , Please correct the mistakes !!!
边栏推荐
- puppeteer入门之 Puppeteer 类
- ESP8266_ Get request weather forecast and JSON parsing
- Drink at night, 50 classic SQL questions, really fragrant~
- 宜居行星
- Detailed explanation of Lora module wireless transceiver communication technology
- Puppeter class of puppeter introduction
- Technology cloud report: privacy computing under the wave of Web3.0
- An error can't locate env pm in @INC
- [Bert]: Calculation of last ave state when training tasks with similar Bert semantics
- B站到底能不能赚到钱?
猜你喜欢

After four years of outsourcing, it was abandoned

Technology cloud report: privacy computing under the wave of Web3.0

ESP8266_ Access to the core suite of Baidu Internet of things and use mqtt protocol for communication

【Objective-C】‘NSAutoreleasePool‘ is unavailable: not available in automatic reference counting mode

oracle 11g rac 磁盘组有空间无法增加数据文件?

Mysql--索引

Interview questions: REM layout, flex layout, etc

Troubleshooting the error ora-12545 reported by scanip in Oracle RAC

Integer lifting example

穆格测试控制器的作用和应用场合有哪些
随机推荐
RAC单独修改scanip到不同网段时会报错
图表背后的秘密 | 技术指标讲解:唐奇安通道
Integer lifting example
[image denoising] image denoising based on median + wavelet + Wiener + filter, including Matlab source code
【Objective-C】结构体和类的区别
对于力士乐电磁换向阀的功能与作用,你知道多少
科技云报道:Web3.0浪潮下的隐私计算
Ora-00059 exceeds DB_ Files limit
Servlet 的初次部署
puppeteer入门之 Browser 类
面试复习之---闭包
ORACLE RAC中连接ScanIP报错ORA-12545的问题解决
Knowledge drop - personality analysis - four types of method
Q1营收超预期,满帮为何赢得逆风增长?
全局池化–Pytorch
The ins-30131 installer failed to verify the required initial settings
Standard dual airbags, Changan Lumin listed, starting at 48900 yuan
With determination to forge ahead, JASMINER continues to deepen its brand strength
Q1营收超华尔街预期,挚文集团的价值等待回归
go连接数据库报错 wsarecv: An existing connection was forcibly closed by the remote host.