likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 8

如果实现了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);
	}
	
	
	

}