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; } }