新聞中心
Spring boot的啟動可以主要分為2個(gè)階段。1 是調(diào)用AbstractApplicationContext的refresh方法之前和調(diào)用AbstractApplicationContext的refresh。 我們知道AbstractApplicationContext的refresh的方法是一個(gè)模板方法。幾乎所有類型的ApplicationContext的初始化都是圍繞這個(gè)refresh方法來進(jìn)行。

成都創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、天壇街道網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5建站、商城網(wǎng)站定制開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為天壇街道等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
1. refresh方法之前
1.1 ApplicationContextInitializer
這個(gè)類Spring boot***進(jìn)行調(diào)用的類,其主要就是初始化一些BeanFactoryPostProcessor(后面會說明),或者一些在Application 初始化的時(shí)候就需要做的事情。而這些類通過通過掃描calsspath路徑下的:META-INF/spring.factories 文件中的org.springframework.context.ApplicationContextInitializer字來加載類的全路徑名,通過反射獲取對象,然后調(diào)用initialize方法。
1.2 ApplicationListener
這個(gè)和ApplicationContextInitializer加載的方式類似,也是從META-INF/spring.factories文件中的配置,主要作用就是在Spring boot的初始化不同階段會處罰不同的事件(ApplicationEvent及其子類),而這些監(jiān)聽器就會根據(jù)自己在不同事件觸發(fā)的情況下完成自己的處理邏輯。例如,ConfigFileApplicationListener負(fù)責(zé)加載配置文件。
當(dāng)然也可以通過其他方式加入beanFactory中,詳情可以參照BeanFactoryPostProcessor加入到beanFactory的方法
1.ApplicationListener的有些事件是在ApplicationContextInitializer之前觸發(fā)的
2.建議不要直接在ApplicationContextInitializer加入自己的BeanFactoryPostProcessor方法,xxxAware是不會幫你注入的。
2. refresh方法
這個(gè)就是spring的模板方法,主要有3個(gè)比較重要的接口
2.1 BeanFactoryPostProcessor
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}這個(gè)方法就是給可以對beanFactory進(jìn)行一些自定義的操作,例如加入一些bean等。當(dāng)然前提就是我們定義的bean是在beanFactory中。有許多辦法可以做到
- 在ApplicationContextInitializer中定義加入,例如
public class MyContextInitializer implements ApplicationContextInitializer{ public void initialize(ConfigurableApplicationContext applicationContext) { applicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor()); } }
- 通過其他BeanFactoryPostProcessor加入,可以通過注解@Import或者加載XML)
例如通過@Import(value={AnnotationBeanDefinitionRegistrar.class})
@Configuration
public class AnnotationBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
private String BEAN_NAME = "annotationBeanPostProcessor";
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
List basePackages = getPackagesToScan(importingClassMetadata);
if (!registry.containsBeanDefinition(BEAN_NAME)) {
addPostProcessor(registry, basePackages);
}
}
private void addPostProcessor(BeanDefinitionRegistry registry, List basePackages) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(AnnotationBeanPostProcessor.class);
beanDefinition.getConstructorArgumentValues()
.addGenericArgumentValue(basePackages);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
}
private List getPackagesToScan(AnnotationMetadata metadata) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(EnableDubbo.class.getName()));
String[] basePackages = attributes.getStringArray("basePackages");
return Arrays.asList(basePackages);
}
} 這樣,就可以加入我們自定義的BeanFactoryPostProcessor,就可以在Bean注冊的層面上進(jìn)行開發(fā)
2.2 BeanPostProcessor
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}這個(gè)接口主要就是針對在bean實(shí)例化前后做一些定制開發(fā)。一般只針對某個(gè)接口或者某個(gè)注解進(jìn)行批量操作
3. 綜述
1. 如果你需要在SpringApplication初始化的時(shí)候就做一些事情,使用ApplicationContextInitializer
2. 如果你需要SpringApplication的某個(gè)特定階段做一些事情,使用ApplicationListener(推薦)
3. 如果你需要在beanFactory層面上開發(fā),使用BeanFactoryPostProcessor(推薦)
4. 如果你需要在對某個(gè)bean的實(shí)例化層面上開發(fā),使用BeanPostProcessor(一般業(yè)務(wù)上的開發(fā)使用InitializingBean或者init-method能夠滿足)
轉(zhuǎn)載請注明出處:https://my.oschina.net/u/3039671/blog/852211
例子,Spring boot風(fēng)格使用dubbo
碼云:https://git.oschina.net/null_584_3382/spring-dubbo-parent
github: https://github.com/Athlizo/spring-dubbo-parent
當(dāng)前題目:談?wù)凷pring boot 啟動層面的開發(fā)
分享URL:http://m.5511xx.com/article/cdopjhe.html


咨詢
建站咨詢
