SpringApplication
SpringApplication Spring Boot 驱动Spring应用上下文的引导类
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
.........
}
@ComponentScan是Spring FrameWork3.1版本开始引入的
@EnableAutoConfiguration:激活自动装配 @Enable->@Enable开头的(Enable开头的取个名字叫激活模式)
- @EnableWebMvc
- @EnableTransactionManagement
- @EnableAspectJAutoProxy
- @EnableAsync
@SpringBootConfiguration:等价于@Configguration ->Configuration Class 注解@Component的"派生性"(阅读Spring注解编程模型:https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model@Component就是下面@Service以及其他的元注解(Meta-Annotations)@Component->@ComponentScan 处理类 -> ConfigurationClassParser扫描类 -> ClassPathBeanDefinitionScanner ClassPathBeanDefinitionScanner ClassPathScanningCandidateComponentProvider
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
........
}
所以我们扫描到的都是Component注解的,也就是下面几个
- @Service
@Component
public @interface Service{
........
}
- @Controller
@Component
public @interface Controller{
........
}
- @Repository
@Component
public @interface Repository{
........
}
- @Configuration
@Component
public @interface Configuration{
........
}
Spring模式注解:Stereotype Annotations(在 Spring 中任何标注 @Component 的组件都可以成为扫描的候选对象这就是模式注解)
Spring注解驱动示例
注解驱动上下文 AnnotionConfigApplicationContext,Spring FrameWork 3.0 开始导入
@Configuration
public class SpringAnnotationDemo {
public static void main(String[] args) {
// XML配置文件驱动 ClassPathXmlApplicationContext
//Annotation驱动 (两者都是找BeanDefinition)
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//注册一个Configuration class = SpringAnnotationDemo
context.register(SpringAnnotationDemo.class);
//上下文启动
context.refresh();
System.out.println(context.getBean(SpringAnnotationDemo.class));
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication标注当前一些功能 @SpringBootApplication @SpringBootConfiguration @Configuration @Component上面就是@SpringBootApplication逐步等同于@Component,也进一步反映了下面所说的@Component的派生性,最终归宿还是Bean
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class)
.properties("server.port=0") //0的意思是随机向操作系统要可用端口
.run(args);
}
Spring Boot引导示例
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Application.class);
Map<String,Object> proprities = new LinkedHashMap<>();
proprities.put("server.port","0");
springApplication.setDefaultProperties(proprities); ConfigurableApplicationContext context = springApplication.run(args);
System.out.println(context.getBean(Application.class));
}
调整示例为非web程序
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Application.class);
Map<String,Object> proprities = new LinkedHashMap<>();
proprities.put("server.port","0");
springApplication.setDefaultProperties(proprities);
//设置为非web应用
springApplication.setWebApplicationType(WebApplicationType.NONE);
ConfigurableApplicationContext context = springApplication.run(args);
System.out.println(context.getBean(Application.class));
//输出当前Spring Boot应用的ApplicationContext的类名
System.out.println("当前Spring应用的上下文的类:"+context.getClass().getName());
}
}
输出:当前Spring应用的上下文的类:org.springframework.context.annotation.AnnotationConfigApplicationContext(这个就是我们前面写的SpringAnnotationDemo里面的context)
配置SpringBoot源
SpringApplication类型推断
当不加以设置Web类型,那么它采用推断
->SpringApplication() -> dedeuceWebApplicationType()第一次推断为WebApplicationType.SERVLET(Spring boot 2.0.3版本,在2.2.1版本deduceEnvironmentClass推断为WebApplicationType.NONE)
WebApplicationType.REACTIVE:Spring WebFlux DispatcherHandler spring-boot-starter-webflux 存在
WebApplicationType.SERVLET:Spring MVV Spring-boot-starter-web 存在
WebApplicationType.NONE:非Web类型 Servlet 不存在 Spring Web上下文 ConfigurableWebApplicationContext 不存在 spring-boot-starter-web 不存在(这个地方就是pom文件里的) spring-boot-starter-webflux 不存在(根据下面的存在与否SpringApplication就能知道是什么环境[环境一说是在2.2.1版本:StandardEnvironment])
人工干预Web类型
设置webApplicationType熟悉为WebApplicationType.NONE
Spring Boot 事件
public class SpringEventListenerDemo {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
//添加事件监听器
// context.addApplicationListener(new ApplicationListener<ApplicationEvent>() {
// @Override
// public void onApplicationEvent(ApplicationEvent event) {
// System.err.println("监听事件:"+event);
// }
// });
//添加自定义监听器
context.addApplicationListener(new ClosedListener());
//启动spring应用上下文
context.refresh();
//两个事件,一个是ContextRefreshedEvent,一个是PayloadApplicationEvent
//Spring应用上下文发布时间
context.publishEvent("HelloWorld");//发布一个HelloWorld内容的事件
//一个是我自己的是事件
context.publishEvent(new MyEvent("HelloWorld 2019"));
//关闭应用上下文
context.close();
}
private static class ClosedListener implements ApplicationListener<ContextClosedEvent>{
@Override
public void onApplicationEvent(ContextClosedEvent event) {
System.out.println("关闭上下文时间"+event);
}
}
private static class MyEvent extends ApplicationEvent{
public MyEvent(Object source) {
super(source);
}
}
}
Spring事件
ContextRefreshedEvent ApplicationContextEvent ApplicationEventrefresh()->finishRefresh() ->publishEvent(new ContextRefreshedEvent(this))
ContextClosedEvent ApplicationContextEvent
ApplicationEvent
refresh()->finishRefresh() ->publishEvent(new ContextRefreshedEvent(this))
自定义事件
PayloadApplicationEvent
Spring事件都是ApplicationEvent类型
发送Spring事件通过ApplicationEventMulticaster#multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType)
Spring事件的类型 ApplicationEvent
Spring事件监听器 ApplicationListener
Spring事件广播器ApplicationEventMulticaster
Spring事件理解为消息
ApplicationEvent相当于消息内容
ApplicationListener 相当于消息消费者,订阅者
ApplicationEventMulticaster 相当于消息生产者,发布者
Spring Boot事件监听示例
@EnableAutoConfiguration
public class SpringBootEventDemo {
public static void main(String[] args) {
new SpringApplicationBuilder(SpringBootEventDemo.class)
.listeners(event -> {
System.out.println("监听到事件:" + event.getClass().getName());
})//增加监听器
.run(args);//运行
}
}
- ApplicationStartingEvent
- ApplicationEnvironmentPreparedEvent
- ApplicationContextInitializedEvent
- ApplicationPreparedEvent
- ContextRefreshedEvent
- ServletWebServerInitializedEvent
- ApplicationStartedEvent
- ApplicationReadyEvent
- ContextClosedEvent
- ApplicationFailedEvent(特殊情况)
SpringBoot事件监听器
org.springframework.context.ApplicationListener=\ org.springframework.boot.ClearCachesApplicationListener,\ org.springframework.boot.builder.ParentContextCloserApplicationListener,\ org.springframework.boot.context.FileEncodingApplicationListener,\ org.springframework.boot.context.config.AnsiOutputApplicationListener,\ org.springframework.boot.context.config.ConfigFileApplicationListener,\ org.springframework.boot.context.config.DelegatingApplicationListener,\ org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\ org.springframework.boot.context.logging.LoggingApplicationListener,\ org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
ConfigFileApplicationListener 监听ApplicationEnvironmentPreparedEvent事件从而加载application.properties或者application.yml文件
Spring boot很多组件依赖于Spring Boot事件监听器实现,本质是Spring FrameWork事件/监听机制
总结就是SpringApplication利用
Spring应用上下文(ApplicationContext)生命周期控制 注解驱动Bean
Spring事件/监听(ApplicationEventMulticaster)机制加载或者初始化组件
来源:https://www.cnblogs.com/zhangliang1726/p/11876453.html