谈谈Spring boot 启动层面的开发
2017-03-05 00:00
197 查看
摘要: Spring boot 的优点和缺点不再讨论的范畴,只是单纯的谈一谈Spring boot的启动过程
Spring boot的启动可以主要分为2个阶段。1 是调用AbstractApplicationContext的refresh方法之前和调用AbstractApplicationContext的refresh。 我们知道AbstractApplicationContext的refresh的方法是一个模板方法。几乎所有类型的ApplicationContext的初始化都是围绕这个refresh方法来进行。
当然也可以通过其他方式加入beanFactory中,详情可以参照BeanFactoryPostProcessor加入到beanFactory的方法
1.ApplicationListener的有些事件是在ApplicationContextInitializer之前触发的
2.建议不要直接在ApplicationContextInitializer加入自己的BeanFactoryPostProcessor方法,xxxAware是不会帮你注入的。
这个方法就是给可以对beanFactory进行一些自定义的操作,例如加入一些bean等。当然前提就是我们定义的bean是在beanFactory中。有许多办法可以做到
在ApplicationContextInitializer中定义加入,例如
通过其他BeanFactoryPostProcessor加入,可以通过注解@Import或者加载XML)
例如通过@Import(value={AnnotationBeanDefinitionRegistrar.class})
这样,就可以加入我们自定义的BeanFactoryPostProcessor,就可以在Bean注册的层面上进行开发
这个接口主要就是针对在bean实例化前后做一些定制开发。一般只针对某个接口或者某个注解进行批量操作
2. 如果你需要SpringApplication的某个特定阶段做一些事情,使用ApplicationListener(推荐)
3. 如果你需要在beanFactory层面上开发,使用BeanFactoryPostProcessor(推荐)
4. 如果你需要在对某个bean的实例化层面上开发,使用BeanPostProcessor(一般业务上的开发使用InitializingBean或者init-method能够满足)
转载请注明出处:https://my.oschina.net/u/3039671/blog/852211
实战文章:https://my.oschina.net/u/3039671/blog/856577
例子,Spring boot风格使用dubbo
码云:https://git.oschina.net/null_584_3382/spring-dubbo-parent
github: https://github.com/Athlizo/spring-dubbo-parent
Spring boot的启动可以主要分为2个阶段。1 是调用AbstractApplicationContext的refresh方法之前和调用AbstractApplicationContext的refresh。 我们知道AbstractApplicationContext的refresh的方法是一个模板方法。几乎所有类型的ApplicationContext的初始化都是围绕这个refresh方法来进行。
1. refresh方法之前
1.1 ApplicationContextInitializer
这个类Spring boot最先进行调用的类,其主要就是初始化一些BeanFactoryPostProcessor(后面会说明),或者一些在Application 初始化的时候就需要做的事情。而这些类通过通过扫描calsspath路径下的:META-INF/spring.factories 文件中的org.springframework.context.ApplicationContextInitializer字来加载类的全路径名,通过反射获取对象,然后调用initialize方法。1.2 ApplicationListener
这个和ApplicationContextInitializer加载的方式类似,也是从META-INF/spring.factories文件中的配置,主要作用就是在Spring boot的初始化不同阶段会处罚不同的事件(ApplicationEvent及其子类),而这些监听器就会根据自己在不同事件触发的情况下完成自己的处理逻辑。例如,ConfigFileApplicationListener负责加载配置文件。当然也可以通过其他方式加入beanFactory中,详情可以参照BeanFactoryPostProcessor加入到beanFactory的方法
1.ApplicationListener的有些事件是在ApplicationContextInitializer之前触发的
2.建议不要直接在ApplicationContextInitializer加入自己的BeanFactoryPostProcessor方法,xxxAware是不会帮你注入的。
2. refresh方法
这个就是spring的模板方法,主要有3个比较重要的接口2.1 BeanFactoryPostProcessor
public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
这个方法就是给可以对beanFactory进行一些自定义的操作,例如加入一些bean等。当然前提就是我们定义的bean是在beanFactory中。有许多办法可以做到
在ApplicationContextInitializer中定义加入,例如
public class MyContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { 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<String> basePackages = getPackagesToScan(importingClassMetadata); if (!registry.containsBeanDefinition(BEAN_NAME)) { addPostProcessor(registry, basePackages); } } private void addPostProcessor(BeanDefinitionRegistry registry, List<String> 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<String> getPackagesToScan(AnnotationMetadata metadata) { AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(EnableDubbo.class.getName())); String[] basePackages = attributes.getStringArray("basePackages"); return Arrays.asList(basePackages); } }
这样,就可以加入我们自定义的BeanFactoryPostProcessor,就可以在Bean注册的层面上进行开发
2.2 BeanPostProcessor
public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
这个接口主要就是针对在bean实例化前后做一些定制开发。一般只针对某个接口或者某个注解进行批量操作
3. 综述
1. 如果你需要在SpringApplication初始化的时候就做一些事情,使用ApplicationContextInitializer2. 如果你需要SpringApplication的某个特定阶段做一些事情,使用ApplicationListener(推荐)
3. 如果你需要在beanFactory层面上开发,使用BeanFactoryPostProcessor(推荐)
4. 如果你需要在对某个bean的实例化层面上开发,使用BeanPostProcessor(一般业务上的开发使用InitializingBean或者init-method能够满足)
转载请注明出处:https://my.oschina.net/u/3039671/blog/852211
实战文章:https://my.oschina.net/u/3039671/blog/856577
例子,Spring boot风格使用dubbo
码云:https://git.oschina.net/null_584_3382/spring-dubbo-parent
github: https://github.com/Athlizo/spring-dubbo-parent
相关文章推荐
- SpringBoot开发入门(二)在Tomcat中启动
- 谈谈 Idea编辑器和SpringBoot轻量框架 初级开发者如何让其启动和访问
- spring boot开发项目,部署到tomcat,启动报错
- spring boot 开发环境禁止热启动
- Spring Boot快速构建我们的开发
- 如何在openshift上diy部署spring-boot并在本地用eclipse开发
- 黑马程序员_加速Java应用开发1:Spring/Hibernate应用调试时启动速度
- SSH开发框架中,实现系统启动加载类,读取数据库常用数据进入内存,利用Spring托管,并完成reload功能
- 用spring+struts2+hibernate开发的项目放到服务器上时由于服务器不能联网,启动tomcat报错。
- Spring Boot实践应用开发(4)
- 使用springBoot进行快速开发
- u-boot1.1.6在NorFlash下启动后实现对Nand的操作(开发用的是sbc2410x_config)
- Spring Boot开发之流水无情(二)
- Spring Boot实践应用开发(3)
- spring boot 启动web,内嵌tomcat
- spring-boot启动
- 加速Java应用开发速度1——加速spring/hibernate应用调试时启动速度
- s3c2440开发日记,u-boot启动过程,Nand Flash启动分析irq_handler, 中断响应过程,
- 加速Java应用开发速度1——加速spring/hibernate应用调试时启动速度
- Spring Boot开发之流水无情(二)