目录
SpringApplication :Spring Boot 驱动 Spring 应用上下文的引导类
1. @SpringBootConfiguration :等价于 @Configuration -->Configuration Class 注解
2.@EnableAutoConfiguration: 激活自动装配 @Enable -> @Enable 开头的
3.@ComponentScan: 它是版本引入的? Spring Framework 3.1
三 Spring 模式注解:Stereotype Annotations
1 什么是约定优于配置
2 从spring常见的注解切入,@configuration/@ComponentScan
3 SpringBoot核心之自动装配原理
4 Spring中的SPI之SpringFactoriesLoader
5 SpringBoot核心之starter,手写一个Stater
6 常见的Starter分析
SpringBoot
1 AutoConfigration
什么是SpringBoot?
SpringBoot帮助我们快速的构建一个基于spring框架的应用,服务于Spring框架的框架,基于约定优于配置的理念简化了繁琐的配置
约定优于配置的体现
1 maven的目录结构 (默认以jar的方式打包,默认会有resource文件夹)
2 对于很多的starter提供了开箱即用的组件
(例如spring-boot-starter-web 提供了内置tomcat,默认将当前项目部署在内置tomcat容器中。
默认的resource/{template/static} 存放静态资源)
3 默认的application.properties 去构建我们的配置
4. 默认通过 spring.profiles.active 属性来决定运行环境时 读取的配置文件
5. EnableAutoConfiguration 默认对于依赖的starter进行 自动装载
SpringApplication
:Spring Boot 驱动 Spring 应用上下文的引导类
一 定义SpringApplication的三种方式
默认方式: 默认端口8080
@SpringBootApplication
public class MicroservicesProjectApplication {
public static void main(String[] args) {
SpringApplication.run(MicroservicesProjectApplication.class, args);
}
new SpringApplication()方式:
@SpringBootApplication
public class MicroservicesProjectApplication {
public static void main(String[] args) {
SpringApplication springApplication= new SpringApplication(MicroservicesProjectApplication.class);
Map<String,Object> properties =new HashMap<>();
properties.put("server.port",0);//使用任意空闲接口
springApplication.setDefaultProperties(properties);
springApplication.run(args);
}
SpringApplicationBuilder 方式:
@SpringBootApplication
public class MicroservicesProjectApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(MicroservicesProjectApplication.class)
.properties("server.port=0")
.run(args);
}
二 @SpringBootApplication 注释解析
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {
@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}
), @Filter( type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
。。。
}
1. @SpringBootConfiguration :等价于 @Configuration -->Configuration Class 注解
:装配自己的configration
- @Configuration 注解标记在类上。就像我们之前声明了一个Spring的XML配置文件,该类我们成为配置类
- @Bean 标记在方法上,方法的返回值会向Spring IOC中注入一个Bean, 其中返回值相当于XML文件中bean标签的class属性,方法名称相当于id属性。
2.@EnableAutoConfiguration
: 激活自动装配 @Enable
-> @Enable
开头的
:import 其他的configration
:除了在import中写死之外,能不能去动态的注入
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
@import 引入外部配置 一起加载
--> xml:<import resource=""/>
动态注入-->根据条件筛选
1,importSelector 来实现
2,importBeanDefinitionRegistrar
动态注入的本质是 在加载 @configuration将Bean注入IOC容器的时候能否做些其他的事情,比如 筛选,判断
@EnableWebMvc
@EnableTransactionManagement
@EnableAspectJAutoProxy
@EnableAsync
3.@ComponentScan
: 它是版本引入的? Spring Framework 3.1
@Component
-> @ComponentScan
等价于xml:<context:component-scan package=''....."/>
@componentScan 扫描 @Component 使得带有这些注解的类被IOC容器托管
处理类 -> ConfigurationClassParser
扫描类 ->
-
ClassPathBeanDefinitionScanner
-
ClassPathScanningCandidateComponentProvider
protected void registerDefaultFilters() { this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ... }
Dubbo
@Service
-> 2.5.7 ->new AnnotationTypeFilter(Service.class);
-
@Component
是一下注解的元注释 (元注释:注释别的注解的注解)
@Service
@Component
public @interface Service {
...
}
@Repository
@Component
public @interface Repository {
...
}
@Controller
@Component
public @interface Controller {
...
}
@Configuration
@Component
public @interface Configuration {
...
}
三 Spring 模式注解:Stereotype Annotations
模式注释是用来声明组件在应用程序中扮演的角色的注释。例如,Spring框架中的“@repository”注释是任何类的标记,这些类实现了存储库(也称为数据访问对象或DAO)的角色或构造型。
@Component 对于任意 spring管理组件 都是通用模式。用“@component”注释的任何组件都是组件扫描的候选组件。类似地,任何用注释注释的组件,如果它本身是用“@component”进行元注释的,那么它也是组件扫描的候选组件。例如,“@service”是用“@component”进行元注释的。
CoreSpring提供了几个现成的原型注释,包括但不限于:@component
、@service
、@repository
、@controller
、@restcontroller
和@configuration
。
@repository
、@service
等是@component
的专门化。
A stereotype annotation is an annotation that is used to declare the role that a component plays within the application. For example, the @Repository
annotation in the Spring Framework is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO).
@Component
is a generic stereotype for any Spring-managed component. Any component annotated with @Component
is a candidate for component scanning. Similarly, any component annotated with an annotation that is itself meta-annotated with @Component
is also a candidate for component scanning. For example, @Service
is meta-annotated with @Component
.
Core Spring provides several stereotype annotations out of the box, including but not limited to: @Component
, @Service
, @Repository
, @Controller
, @RestController
, and @Configuration
. @Repository
, @Service
, etc. are specializations of @Component
.
四 spring注解驱动和SpringBoot的关系
注解驱动上下文 AnnotationConfigApplicationContext
, Spring Framework 3.0 开始引入的
@Configuration
public class SpringAnnotationDemo {
public static void main(String[] args) {
// XML 配置文件驱动 ClassPathXmlApplicationContext
// Annotation 驱动
// 找 BeanDefinition @Bean @Configuration
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 注册一个 Configuration Class = SpringAnnotationDemo
context.register(SpringAnnotationDemo.class);
// 上下文启动
context.refresh();
System.out.println(context.getBean(SpringAnnotationDemo.class));
}
}
@SpringBootApplication
public class MicroservicesProjectApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(MicroservicesProjectApplication.class);
Map<String, Object> properties = new LinkedHashMap<>();
properties.put("server.port", 0);
springApplication.setDefaultProperties(properties);
// 设置为 非 web 应用
springApplication.setWebApplicationType(WebApplicationType.NONE);
ConfigurableApplicationContext context = springApplication.run(args);
// 有异常?
System.out.println(context.getBean(MicroservicesProjectApplication.class));
// 输出当前 Spring Boot 应用的 ApplicationContext 的类名
System.out.println("当前 Spring 应用上下文的类:" + context.getClass().getName());
}
}
打印结果:
com.gupao.microservicesproject.MicroservicesProjectApplication$$EnhancerBySpringCGLIB$$5dba78be@3ecd267f
当前 Spring 应用上下文的类:org.springframework.context.annotation.AnnotationConfigApplicationContext
@SpringBootApplication
标注当前一些功能
-
@SpringBootApplication 被@SpringBootConfiguration 注释
-
@SpringBootConfiguration 被@Configuration注释
-
@Configuration 被@Component注释
-
@Component
-
-
-
SpringApplication
Spring Boot 应用的引导 也是基于 AnnotationConfigApplicationContext 的
五,SpringAppliation 类型推断
当不加以设置 Web 类型,那么它采用推断:
-> SpringAppliation()
-> deduceWebApplicationType()
第一次推断为 WebApplicationType.SERVLET
-
WebApplicationType.NONE
: 非 Web 类型-
Servlet
不存在 -
Spring Web 应用上下文
ConfigurableWebApplicationContext
不存在-
spring-boot-starter-web
不存在 -
spring-boot-starter-webflux
不存在
-
-
-
WebApplicationType.REACTIVE
: Spring WebFlux-
DispatcherHandler
-
spring-boot-starter-webflux
存在
-
-
Servlet
不存在-
spring-boot-starter-web
不存在
-
-
-
WebApplicationType.SERVLET
: Spring MVC-
spring-boot-starter-web
存在
-
结论:springBoot 采用控制依赖的方式控制程序的
人工干预 Web 类型
设置 webApplicationType 属性 为 WebApplicationType.NONE
六 SpringBoot事件监听事例
@SpringBootApplication
public class SpringBootVincentApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SpringBootVincentApplication.class)
.listeners(applicationEvent -> {
System.err.println("监听到事件:"+applicationEvent.getClass().getName());
})
.run(args);
}
}
监听到事件:org.springframework.boot.context.event.ApplicationStartingEvent
监听到事件:org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent
监听到事件:org.springframework.boot.context.event.ApplicationContextInitializedEvent
监听到事件:org.springframework.boot.context.event.ApplicationPreparedEvent
监听到事件:org.springframework.context.event.ContextRefreshedEvent
监听到事件:org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent
监听到事件:org.springframework.boot.context.event.ApplicationStartedEvent
监听到事件:org.springframework.boot.context.event.ApplicationReadyEvent
七 Spring Boot 事件监听器
# Application Listeners
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 事件/监听机制
SpringBoot 利用 控制依赖的方式控制程序
SpringApplication 利用 spring 应用上下文(ApplicationContext)生命周期 控制注解 驱动Bean
SpringApplication利用 Spring 事件/监听(ApplicationEventMulticaster)机制加载或者初始化组件