如果实现了BeanFactoryPostProcessor接口,则@PostConstruct和@PreDestroy和@Value将不起作用

本文介绍了Spring框架中的BeanFactoryPostProcessor接口,其在BeanFactory实例化和配置bean之前提供后置处理能力。同时讨论了BeanPostProcessor,以及两者在处理时机和功能上的区别,以及@PostConstruct和@PreDestroy注解在不同场景下的使用情况。
摘要由CSDN通过智能技术生成

如果实现了BeanFactoryPostProcessor接口,则@PostConstruct和@PreDestroy和@Value将不起作用

如果实现了BeanFactoryPostProcessor接口,则@PostConstruct和@PreDestroy和@Value将不起作用







BeanFactoryPostProcessor

BeanFactoryPostProcessor是Spring框架中的一个接口,用于在BeanFactory实例化和配置bean之前对BeanFactory进行后置处理。它允许开发人员在Spring容器加载bean定义文件并实例化bean之前修改BeanFactory的行为。

BeanFactoryPostProcessor接口有一个方法postProcessBeanFactory,该方法在Spring容器加载bean定义文件之后,但在实例化和配置bean之前被调用。在这个方法中,开发人员可以对BeanFactory进行任何必要的修改,例如添加或删除bean定义,修改bean的属性等。

以下是一个示例,演示了如何实现BeanFactoryPostProcessor接口并使用postProcessBeanFactory方法来修改BeanFactory的行为:

import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 在这里可以对BeanFactory进行修改
        // 例如添加或删除bean定义,修改bean的属性等
    }
}

在上面的示例中,我们创建了一个名为MyBeanFactoryPostProcessor的类,实现了BeanFactoryPostProcessor接口,并重写了postProcessBeanFactory方法。在这个方法中,我们可以根据需要对BeanFactory进行修改。

注意:BeanFactoryPostProcessor的执行顺序是在BeanPostProcessor之前。

BeanFactoryPostProcessor是Spring框架中的一个重要接口,它允许我们在Spring的IoC容器准备好之后,但在bean实例化之前,对bean的定义进行自定义修改。这个接口的实现类可以访问和修改容器中bean的属性、元数据甚至是整个bean定义。

当Spring IoC容器读取了所有的bean配置信息,并且将这些信息存储到BeanDefinitionRegistry中后,它会初始化所有的BeanFactoryPostProcessor。然后,这些BeanFactoryPostProcessor就可以按照它们自己的逻辑去修改存储在容器中的bean定义了。

典型的BeanFactoryPostProcessor实现包括PropertyPlaceholderConfigurer,它用于处理占位符并替换为实际的属性值。

BeanFactoryPostProcessor的工作流程大致如下:

  1. 容器创建BeanFactoryPostProcessor实例。
  2. 容器调用BeanFactoryPostProcessorpostProcessBeanFactory方法。
  3. postProcessBeanFactory方法中,开发者可以获取到ConfigurableListableBeanFactory,并对bean定义进行自定义的修改。

需要注意的是,BeanFactoryPostProcessor是对整个Spring容器的bean定义进行修改,而BeanPostProcessor则是对单个bean实例进行初始化前和初始化后的处理。这两者虽然名字相似,但处理的对象和时机是不同的。

此外,关于@PostConstruct@PreDestroy注解在BeanFactoryPostProcessor实现类中的使用,通常这些注解是用于处理单个bean实例的生命周期回调的。而BeanFactoryPostProcessor处理的是bean定义,因此在BeanFactoryPostProcessor实现类中使用这些注解可能没有意义,因为此时还没有bean实例被创建。

如果你需要在BeanFactoryPostProcessor执行之后进行一些初始化操作,可以考虑使用InitializingBean接口和它的afterPropertiesSet方法,或者简单地使用一个初始化的@Bean方法,在这个方法中执行所需的操作。然而,这些方法仍然是在bean实例层面上的,而不是在bean定义层面上。如果你真的需要在bean定义被修改后执行某些操作,你可能需要自定义一个BeanFactoryPostProcessor并在postProcessBeanFactory方法中直接执行这些操作。







BeanFactoryPostProcessor 和 BeanPostProcessor 的区别

BeanFactoryPostProcessorBeanPostProcessor都是Spring框架中用于扩展和自定义bean处理的接口,但它们在处理时机和处理内容上有所不同。

  1. 处理时机:

    • BeanFactoryPostProcessor:在Spring IoC容器初始化之后,但在bean实例化之前调用。这意味着所有的bean定义已经被加载到BeanFactory中,但尚未创建bean的实例。BeanFactoryPostProcessor允许你访问和修改存储在容器中的bean定义。
    • BeanPostProcessor:在bean实例化之后,但在bean的初始化方法(如@PostConstruct注解的方法或实现了InitializingBean接口的afterPropertiesSet方法)之前和之后调用。它允许你对已经实例化的bean对象进行修改或包装。
  2. 处理内容:

    • BeanFactoryPostProcessor:主要处理bean的定义(配置元数据),比如修改bean的属性值或向容器中注入其他的bean定义信息。它提供了对整个BeanFactory的访问,并可以对其中的bean定义进行全局的修改。
    • BeanPostProcessor:主要处理bean实例,可以在bean初始化前后对其进行操作,比如生成bean的动态代理对象、修改bean的属性等。它是针对每个bean实例逐一处理的。
  3. 典型用途:

    • BeanFactoryPostProcessor:典型的用途包括配置占位符的替换(如PropertyPlaceholderConfigurer)、向容器中添加或覆盖bean定义等。
    • BeanPostProcessor:典型的用途包括自动装配、AOP代理的创建、检查bean属性的合法性等。
  4. 注册和使用:

    • BeanFactoryPostProcessor:需要实现postProcessBeanFactory方法,并通过Spring配置文件或注解方式将其注册为Spring bean。Spring容器会自动调用所有注册的BeanFactoryPostProcessor实例的postProcessBeanFactory方法。
    • BeanPostProcessor:需要实现postProcessBeforeInitialization和/或postProcessAfterInitialization方法,并通过Spring配置文件或注解方式将其注册为Spring bean。每当容器创建一个bean实例时,都会自动调用这些方法来执行自定义逻辑。

BeanFactoryPostProcessor和BeanPostProcessor是Spring框架中用于对Bean进行后处理的两个接口,它们在使用上有以下区别:

  1. 作用对象不同:

    • BeanFactoryPostProcessor是对整个Bean工厂进行处理的,可以在Bean实例化之前修改Bean的定义或配置。
    • BeanPostProcessor是对每个Bean实例进行处理的,可以在Bean实例化后、依赖注入之前或之后对Bean进行修改。
  2. 执行顺序不同:

    • BeanFactoryPostProcessor在Bean实例化之前执行,用于修改Bean的定义或配置。
    • BeanPostProcessor在Bean实例化后、依赖注入之前或之后执行,用于对Bean进行增强或修改。
  3. 功能不同:

    • BeanFactoryPostProcessor可以修改Bean的定义或配置,例如修改Bean的属性值、添加新的Bean定义等。
    • BeanPostProcessor可以对Bean进行增强或修改,例如在Bean实例化后添加额外的逻辑、修改Bean的属性值等。

总结起来,BeanFactoryPostProcessor是对整个Bean工厂进行处理的,用于修改Bean的定义或配置;而BeanPostProcessor是对每个Bean实例进行处理的,用于对Bean进行增强或修改。







测试代码1
package z24dec.msbtLifeCycle;

import static java.lang.System.out;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.*;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;


@Component
@Configuration
public class LifeCycleTest2403110139 implements BeanNameAware, BeanFactoryAware
//, BeanFactoryPostProcessor
//, BeanPostProcessor
//, InstantiationAwareBeanPostProcessor   //  public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor 
, InitializingBean
, DisposableBean
{
	
	public static void pln(Object o) {
		out.println(o);
	}
	
	public LifeCycleTest2403110139() {
		pln(this.getClass().getName() +  "的构造方法");
	}
	
	
	private Object property001;

	public Object getProperty001() {
		return property001;
	}
	
	@Value("${property001:默认值} ABC abc 👆👇👈👉 Hello World 你好世界")
	public void setProperty001(Object property001) {
		this.property001 = property001.toString();
		pln(this.getClass().getName() +  "的成员变量(属性)的SETTER方法");
	}

	@Override
	public void setBeanName(String name) {
		pln(this.getClass().getName() +  "实现BeanNameAware接口的setBeanName(String name)方法, name="+name);
		
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		pln(this.getClass().getName() +  "实现BeanFactoryAware接口的setBeanFactory(BeanFactory beanFactory)方法, beanFactory="+beanFactory);
		
	}

//	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		pln(this.getClass().getName() +  "实现BeanPostProcessor接口的postProcessBeforeInitialization(Object bean, String beanName)方法, bean=" + bean + "   ,   beanName="+beanName);
//		return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
		return null;
	}

	public void 业务方法010() {
		pln(this.getClass().getName() +  "的业务方法010");
	}
	
//	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		pln(this.getClass().getName() +  "实现BeanPostProcessor接口的postProcessAfterInitialization(Object bean, String beanName)方法, bean=" + bean + "   ,   beanName="+beanName);
//		return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
		return null;
	}
	
	@PostConstruct    // 如果实现了BeanFactoryPostProcessor, 则@PostConstruct不起作用
	void postConstruct() {
		pln(this.getClass().getName() +  "的添加了@PostConstruct的方法");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		pln(this.getClass().getName() +  "实现InitializingBean接口的afterPropertiesSet()方法, 无参");
		
	}
	
	@PreDestroy    // 如果实现了BeanFactoryPostProcessor, 则@PreDestroy不起作用
	public void preDestroy() {
		pln(this.getClass().getName() +  "的添加了@PreDestroy的方法");
	}

	
	public void destroy() throws Exception {
		pln(this.getClass().getName() +  "实现DisposableBean接口的destroy()方法, 无参");
		
	}

	
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		pln(this.getClass().getName() +  "实现BeanFactoryPostProcessor接口的postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法, beanFactory="+beanFactory);
	}
	
	
	

}













  • 28
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据提供的引用内容,@PostConstruct注解用于在依赖注入完成后执行初始化操作的方法上。它会在类被放入服务之前被调用。然而,在BeanFactoryPostProcessor中使用@PostConstruct注解可能会导致失效。\[1\]这可能是由于BeanFactoryPostProcessorBean的实例化和初始化之前执行,因此@PostConstruct注解可能无法正常工作。\[2\] 如果你想在所有BeanDefinition注册完成后执行某些操作,你可以考虑使用单独的Bean来处理。这样可以确保在所有Bean被实例化和初始化之后再执行相应的逻辑。\[1\] 如果你想更新使用@PostConstruct注解注入的Bean,你可以考虑使用其他方式,如使用BeanPostProcessor接口来处理Bean的初始化逻辑。BeanPostProcessor接口提供了在Bean实例化和初始化过程中进行自定义处理的方法。你可以实现这个接口,并在postProcessBeforeInitialization或postProcessAfterInitialization方法中进行相应的操作。\[3\]这样可以确保在Bean的初始化过程中进行更新操作。 #### 引用[.reference_title] - *1* *2* [@PostConstruct 失效之(Bean实现BeanFactoryPostProcessor)](https://blog.csdn.net/qq_41653935/article/details/124092601)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [spring @PostConstruct以及循环依赖的bean](https://blog.csdn.net/weixin_45594127/article/details/121809206)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kfepiza

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值