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

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM