Spring扩展接口-BeanFactoryPostProcessor

简介

Spring启动部分流程:

  • Spring IOC读取Bean的相关属性,保存到beanDefinition对象中。
  • 加载完所有beanDefinition之后,调用BeanFactoryPostProcessor接口扩展点。
  • 根据beanDefinition创建bean对象。

如果想获取beanDefinition信息或者修改BeanDefinition对象中的属性, 可以实现BeanFactoryPostProcessor进行修改。

public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

用途示例

Spring应用读取配置

抽象类:PropertyResourceConfigurer, 主要做的就是读取properties文件,做一些必要的转换,并将这些properties写到bean Definition中。

public abstract class PropertyResourceConfigurer extends PropertiesLoaderSupport
	implements BeanFactoryPostProcessor, PriorityOrdered {

		
	private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered

	// 略:serOrder / getOrder

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		try {
			Properties mergedProps = mergeProperties();

			// Convert the merged properties, if necessary.
			convertProperties(mergedProps);

			// Let the subclass process the properties.
			processProperties(beanFactory, mergedProps);
		} catch (IOException ex) {
				throw new BeanInitializationException("Could not load properties", ex);
		}
	}
}

它有两个实现类:

  • PropertyOverrideConfigurer:比如数据库配置为"dataSource.driverClassName=com.mysql.jdbc.Driver",这个类负责将这个value从配置文件中(比如叫datasource.properties)读取配置写到相应的beanDefinition中。

  • PropertyPlaceholderConfigurer ,这个类可以将代码中定义的"${...}"替换为配置文件中的实际的值。

在Spring启动时打印相关信息, 比如bean的个数,统计指定特性的bean信息,修改beanDefinition, 甚至注册BeanDefinition。

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
		
		int count = defaultListableBeanFactory.getBeanDefinitionCount();
        System.out.println("[MyBeanFactoryPostProcessor]当前beanFactory共有" + count + "个bean");
        
		String[] beanDefinitionNames = defaultListableBeanFactory.getBeanDefinitionNames();
      
        //修改属性
        for (String beanName : beanDefinitionNames) {
            if ("person".equals(beanName)) {
                //获取PersonDefinition对象
                BeanDefinition beanDefinition = defaultListableBeanFactory.getBeanDefinition(beanName);
                MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
                System.out.println(propertyValues.toString());
                //修改定义中的name属性值
                propertyValues.addPropertyValue("name", "赵四");
                System.out.println("[MyBeanFactoryPostProcessor]postProcessBeanFactory方法中修改了name属性初始值了");
            }
        }


        //手动注册User的BeanDefiniton
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class); 
        beanDefinitionBuilder.addPropertyValue("id", 123);
        beanDefinitionBuilder.addPropertyValue("name", "修改definition");
        defaultListableBeanFactory.removeBeanDefinition("user");
        defaultListableBeanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
    }
}

更多信息请移步Spring专栏:www.yuque.com/mrhuang-ire…

posted @ 2023-10-12 10:07  扎Zn了老Fe  阅读(8)  评论(0编辑  收藏  举报  来源