Spring Boot源码:BeanFactoryPostProcessor和BeanPostProcessor
Posted SunSAS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot源码:BeanFactoryPostProcessor和BeanPostProcessor相关的知识,希望对你有一定的参考价值。
BeanFactoryPostProcessor是spring BeanFactory加载Bean后调用,
BeanPostProcessor是Bean初始化前后调用。
BeanFactoryPostProcessor
通俗地说:BeanFactoryPostProcessor是胚胎中直接基因改造,BeanPostProcessor是出生后去整容。
上面是refresh()方法的一部分,之前还调用了
prepareBeanFactory(beanFactory);
配置beanFactory
invokeBeanFactoryPostProcessors(beanFactory);
这个方法去执行BeanFactoryPostProcessor下的类。包括自己定义的一些类,mybatis 整合spring就是通过这个。但我们写crud是不用这些东西的,只看一个简单的demo:
新建一个类实现BeanFactoryPostProcessor :
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("people"); genericBeanDefinition.setBeanClass(User.class); ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); constructorArgumentValues.addIndexedArgumentValue(0,"abc"); genericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); } }
实现postProcessBeanFactory()方法,在这个方法中拿到people的beanDefinition,这里用子类去接收,因为子类api更丰富,
然后修改他的beanClass为User类(注意User类没有注入Spring 容器):
public class User { }
运行Test main方法:
public class Test { public static void main(String[] args) { //通过注解配置类初始化 spring上下文 AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MyConfig.class); //还有一种通过xml来初始化 spring上下文,这里就不介绍了。 //ClassPathXmlApplicationContext System.out.println(annotationConfigApplicationContext.getBean("people")); } }
输出结果为:
component.User@4671e53b
所以我们可以通过BeanFactoryPostProcessor修改beanDefinition。
其中还有两个属性简单说下
autowireMode:自动装配模型。可以设置4个值:
/**
* Constant that indicates no externally defined autowiring. Note that
* BeanFactoryAware etc and annotation-driven injection will still be applied.
*/
int AUTOWIRE_NO = 0;
/**
* Constant that indicates autowiring bean properties by name
* (applying to all bean property setters).
*/
int AUTOWIRE_BY_NAME = 1;
/**
* Constant that indicates autowiring bean properties by type
* (applying to all bean property setters).
*/
int AUTOWIRE_BY_TYPE = 2;
/**
* Constant that indicates autowiring the greediest constructor that
* can be satisfied (involves resolving the appropriate constructor).
*/
int AUTOWIRE_CONSTRUCTOR = 3;
默认是0,不自动装配。
如果设置为1,2。那么该类下的依赖不需要@Autowired或@Resource注解了
@Component public class People { private User user; }
对people的beanDefinition设置自动装配,则user也可以正常使用,而不会NPE。
constructorArgumentValues:这个参数会决定bean实例化时调用的构造方法,默认是无参构造器。
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues(); constructorArgumentValues.addIndexedArgumentValue(0,"abc"); genericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues);
这里会调用的是一个参数是字符串的构造方法。
BeanPostProcessor
BeanPostProcessor称为后置处理器,spring框架中很多技术实现了此接口。例如自动注入等,spring中使用了5个子类初始化bean。这个以后再说
此方法中:
这里调用的方法就是实例化前和实例化后。
使用示例:
@Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean); return bean; } }
以上是关于Spring Boot源码:BeanFactoryPostProcessor和BeanPostProcessor的主要内容,如果未能解决你的问题,请参考以下文章
Spring源码 BeanFactory和FactoryBean是什么?