• 2-3.spring源码--BeanFactoryPostProcessor


    Spring源码–BeanFactoryPostProcessor

    对于BeanFactoryPostProcessor下面是官方api文档给出的定义:

    连接工厂允许修改自定义应用的bean信息,可以调整底层bean工厂的属性值。(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.)
    
    • 1

    从上面 的文档上看就是可以修改bean信息,但是修改的触发节点是在bean实例化前才会有效果 。看下BeanFactoryPostProcessor的源码:

    
    public interface BeanFactoryPostProcessor {
    	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    从源码中可以看出,这个接口只有一个接口,所有的实现都是集成这个接口,下面 是实现接口的对应类型。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ShhFCT61-1661767517508)(..\picture\14.png)]

    下面看下这个其中一个的源码:

    		public BeanFactoryPostProcessor beanFactoryPostProcessor() {
    			return new BeanFactoryPostProcessor() {
    				@Override
    				public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    					BeanDefinition bd = beanFactory.getBeanDefinition("beanPostProcessor");
    					bd.getPropertyValues().addPropertyValue("nameSuffix", "-processed-" + myProp);
    				}
    			};
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    以上核心代码只有两个句,第一步:BeanDefinition bd = beanFactory.getBeanDefinition(“beanPostProcessor”);通过bean工厂 获取到BeanDefinition的对象。第二步:bd.getPropertyValues().addPropertyValue(“nameSuffix”, “-processed-” + myProp);对于bean加入 属性。

    下面我们举个栗子,看下BeanFactoryPostProcessor使用情况:

    集成BeanFactoryPostProcessor接口,实现重写postProcessBeanFactory方法:

    public class NameBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		System.out.println("-->NameBeanFactoryPostProcessor start");
    		String[] names = beanFactory.getBeanDefinitionNames();
    		for (String name : names) {
    			if("a".equals(name)){
    
    				BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
    				MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
    				if(propertyValues.contains("name")){
    					propertyValues.addPropertyValue("name", "王五");
    					System.out.println("-->mod bean definition name");
    				}
    			}
    		}
    		System.out.println("-->NameBeanFactoryPostProcessor  end");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    执行触发方法:

    public class TestAB {
    	public static void main(String[] args) {
    		ApplicationContext applicationContext= new ClassPathXmlApplicationContext("x.xml");
    		A a=applicationContext.getBean(A.class);
    		System.out.println("-->NameBeanFactoryPostProcessor test end!");
    		System.out.println("-->name :"+ a.getName());
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    看下A类的xml的文件内容:

    	
    		
    	
    
    • 1
    • 2
    • 3

    执行结果:

    -->NameBeanFactoryPostProcessor start
    -->mod bean definition name
    -->NameBeanFactoryPostProcessor  end
    -->BeanFactoryPostProcessor test end!
    -->name :王五
    
    • 1
    • 2
    • 3
    • 4
    • 5

    A类的属性被修改了 , 从张三 -> 王五。

    下面思考一个问题,如果有多个BeanFactoryPostProcessor存在怎么办?

    这时候给A类加一个age属性,再添加AgeBeanFactoryPostProcessor,这时有两个BeanFactoryPostProcessor,这时就用到了我们之前降到的AbstractApplicationContext实现类中的refresh方法,在refresh方法中有进行,回顾一下refresh方法与beanFactory相关的四个方法:

    			//创建
    			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    			//准备	
    			prepareBeanFactory(beanFactory);
    			//空方法
    			postProcessBeanFactory(beanFactory);
    			//处理逻辑
    			invokeBeanFactoryPostProcessors(beanFactory);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    进入invokeBeanFactoryPostProcessors(beanFactory)展示源码:

    	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    		//逻辑处理
    		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    		//后续处理
    		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());方法中,查看源码

    	public static void invokeBeanFactoryPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
    			
    		//......省略了部分代码,代码太长了,了解这块内容看这里就行了
    
    		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    		//首先,调用实现 PriorityOrdered 的 BeanFactoryPostProcessor。
    		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    		//接下来,调用实现 Ordered 的 BeanFactoryPostProcessors。
    		List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    		for (String postProcessorName : orderedPostProcessorNames) {
    			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		sortPostProcessors(orderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    		// Finally, invoke all other BeanFactoryPostProcessors.
    		//最后,调用所有其他 BeanFactoryPostProcessor。
    		List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    		for (String postProcessorName : nonOrderedPostProcessorNames) {
    			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在上面源码中可以看出,在执行优先级 实现PriorityOrdered > 实现Ordered > 其他 。所以PriorityOrdered 和Ordered 是影响BeanFactoryPostProcessors执行顺序的最终因素。下面看下PriorityOrdered 和Ordered 源码:

    public interface PriorityOrdered extends Ordered {
    }
    
    public interface Ordered {
    
    	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
    
    	int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
    
    	/**
    	 * Get the order value of this object.
    	 * 

    Higher values are interpreted as lower priority. As a consequence, * the object with the lowest value has the highest priority (somewhat * analogous to Servlet {@code load-on-startup} values). *

    Same order values will result in arbitrary sort positions for the * affected objects. * @return the order value * @see #HIGHEST_PRECEDENCE * @see #LOWEST_PRECEDENCE */ int getOrder(); }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    从源码上可以看出来PriorityOrdered是继承了Ordered接口,所以下面我们以Ordered接口为例,去验证多个BeanFactoryPostProcessors类。

    NameBeanFactoryPostProcessor类
    
    public class NameBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		System.out.println("-->NameBeanFactoryPostProcessor start");
    		String[] names = beanFactory.getBeanDefinitionNames();
    		for (String name : names) {
    			if("a".equals(name)){
    
    				BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
    				MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
    				if(propertyValues.contains("name")){
    					propertyValues.addPropertyValue("name", "王五");
    					System.out.println("-->mod bean definition name");
    				}
    			}
    		}
    		System.out.println("-->NameBeanFactoryPostProcessor  end");
    	}
    
    	@Override
    	public int getOrder() {
    		return 1;
    	}
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    AgeBeanFactoryPostProcessor类
    public class AgeBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		System.out.println("-->AgeBeanFactoryPostProcessor start");
    		String[] names = beanFactory.getBeanDefinitionNames();
    		for (String name : names) {
    			if("a".equals(name)){
    
    				BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
    				MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
    				if(propertyValues.contains("name")){
    					propertyValues.addPropertyValue("age", 12);
    					System.out.println("-->mod bean definition age");
    				}
    			}
    		}
    		System.out.println("-->AgeBeanFactoryPostProcessor  end");
    	}
    
    	@Override
    	public int getOrder() {
    		return 2;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    x.xml文件
    	
    		
    		
    	
    	
    	
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    启动方法
    	public static void main(String[] args) {
    		ApplicationContext applicationContext= new ClassPathXmlApplicationContext("x.xml");
    		A a=applicationContext.getBean(A.class);
    		System.out.println("-->BeanFactoryPostProcessor test end!");
    		System.out.println("-->name :"+ a.getName());
    		System.out.println("-->age :"+ a.getAge());
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    执行结果

    -->NameBeanFactoryPostProcessor start
    -->mod bean definition name
    -->NameBeanFactoryPostProcessor  end
    -->AgeBeanFactoryPostProcessor start
    -->mod bean definition age
    -->AgeBeanFactoryPostProcessor  end
    -->BeanFactoryPostProcessor test end!
    -->name :王五
    -->age :12
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    从输出结果上看确实是先执行的NameBeanFactoryPostProcessor,后置执行的AgeBeanFactoryPostProcessor,与设置的order数字是一致的。

    坚持吧!!! 坚持卷spring源码

  • 相关阅读:
    数据治理基础
    Mongodb安全访问控制操作案例
    web前端期末大作业:基于HTML+CSS+JavaScript实现网上鲜花店网站设计(14页)
    centos7 安装 qt5.14.2 以及 openssl 问题
    浅谈JVM垃圾回收机制
    【每日一题】力扣1768. 交替合并字符串
    Express操作MongoDB
    【MySQL】MySQL的安装,登录,配置和相关命令
    【组成原理-存储】关于交叉存储器检测访问冲突的一种算法
    Linux红帽(RHCE)认证学习笔记 - (2)用户组和用户的管理
  • 原文地址:https://blog.csdn.net/smd2575624555/article/details/126589972