作者:俊谚怡雯綺修 | 来源:互联网 | 2023-09-24 11:35
BeanFactoryPostProcessor是springBeanFactory加载Bean后调用,BeanPostProcessor是Bean初始化前后调用。BeanFact
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 容器):
运行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;
}
}