在此係列文章中,我總結了Spring幾乎所有的擴充套件介面,以及各個擴充套件點的使用場景。並整理出一個bean在spring中從被載入到最終初始化的所有可延伸點的順序呼叫圖。這樣,我們也可以看到bean是如何一步步載入到spring容器中的。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException; }
BeanDefinitionRegistryPostProcessor為容器級後置處理器。容器級的後置處理器會在Spring容器初始化後、重新整理前執行一次。還有一類為Bean級後置處理器,在每一個Bean範例化前後都會執行。
通常,BeanDefinitionRegistryPostProcessor用於在bean解析後範例化之前通過BeanDefinitionRegistry對BeanDefintion進行增刪改查。
常見如mybatis的Mapper介面注入就是實現的此介面。
下面是一個範例,展示瞭如何實現動態的給spring容器新增一個Bean:
public class User {
String name;
String password;
}
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
@Component
public class DynamicBeanRegistration implements BeanDefinitionRegistryPostProcessor, Ordered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanRegistry) throws BeansException {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(User.class);
MutablePropertyValues propertyValues = new MutablePropertyValues();
PropertyValue propertyValue1 = new PropertyValue("name", "張三");
PropertyValue propertyValue2 = new PropertyValue("password", "123456");
propertyValues.addPropertyValue(propertyValue1);
propertyValues.addPropertyValue(propertyValue2);
beanDefinition.setPropertyValues(propertyValues);
beanRegistry.registerBeanDefinition("user", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
System.out.println(beanDefinition.getBeanClassName());
User user = beanFactory.getBean(User.class);
System.out.println(user.getName());
System.out.println(user.getPassword());
}
@Override
public int getOrder() {
return 0;
}
}
輸出:
com.sandy.springex.beanfefinitionregistrypostprocessor.User
張三
123456
該程式碼通過實現BeanDefinitionRegistryPostProcessor介面,在Spring容器啟動時動態註冊了一個名為"user"的Bean,並設定了其name和password屬性的值。在後續的BeanFactory初始化過程中,可以通過beanFactory獲取到該動態註冊的Bean,並存取其屬性值。
當容器中有多個BeanDefinitionRegistryPostProcessor的時候,可以通過實現Ordered介面來指定順序:
@Override
public int getOrder() {
return 0; //值越小,優先順序越高
}