Spring Boot 编程思想|理解@SpringBootApplication
文章目录
@SpringBootApplication注解语义
SpringBoot 2.1.9
官方文档18. Using the @SpringBootApplication Annotation
Many Spring Boot developers like their apps to use auto-configuration, component scan and be able to define extra configuration on their “application class”. A single
@SpringBootApplication
annotation can be used to enable those three features, that is:
@EnableAutoConfiguration
: enable Spring Boot’s auto-configuration mechanism@ComponentScan
: enable@Component
scan on the package where the application is located (see the best practices)@Configuration
: allow to register extra beans in the context or import additional configuration classesThe
@SpringBootApplication
annotation is equivalent to using@Configuration
,@EnableAutoConfiguration
, and@ComponentScan
with their default attributes, as shown in the following example
@SpringBootApplication
被用于激活@EnableAutoConfiguration
、@ComponentScan
、@Configuration
三个注解的特性。
@EnableAutoConfiguration
负责激活Spring Boot的自动装配机制@ComponentScan
激活@Component
的扫描@Configuration
声明标注为配置类
注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
启动类代码
@SpringBootApplication
public class AppBootstrap {
public static void main(String[] args) {
SpringApplication.run(AppBootstrap.class, args);
}
}
等同于
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class AppBootstrap {
public static void main(String[] args) {
SpringApplication.run(AppBootstrap.class, args);
}
}
不过@ComponentScan
增加了排除的FilterType
实现
- TypeExcludeFilter
SpringBoot 1.4
引入,用于查找BeanFactory
中已注册的TypeExcludeFilter Bean
,作为代理执行对象
- AutoConfigurationExcludeFilter
SpringBoot 1.5
开始支持,用于排除其他同时标注@Configuration
和@Configuration @EnableAutoConfiguration
的类
@SpringBootApplication属性别名
public @interface SpringBootApplication {
/**
* ...
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
/**
* ...
* @since 1.3.0
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
/**
* ...
* @since 1.3.0
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
/**
* ...
* @since 1.3.0
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
以上所有属性方法上都标有@AliasFor
注解,它是用于桥接其他注解的属性。
比如重新设置basePackages
属性
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
启动类代码
@SpringBootApplication(scanBasePackages = "com.huajie.springboot.sample.spring.application.config")
public class AppBootstrap {
public static void main(String[] args) {
SpringApplication.run(AppBootstrap.class, args);
}
}
扫描包的路径将会修改成"com.huajie.springboot.sample.spring.application.config"指定路径
理解自动配置机制
SpringBoot 2.1.9
官方文档49. Creating Your Own Auto-configuration
If you work in a company that develops shared libraries, or if you work on an open-source or commercial library, you might want to develop your own auto-configuration. Auto-configuration classes can be bundled in external jars and still be picked-up by Spring Boot.
Auto-configuration can be associated to a “starter” that provides the auto-configuration code as well as the typical libraries that you would use with it. We first cover what you need to know to build your own auto-configuration and then we move on to the typical steps required to create a custom starter.
自动装配类能打包到外部的jar
文件中,并且被Spring Boot装载。同时自动装配也能被关联到starter
中,这些starter
提供自动装配的代码和关联的依赖。
49.1 Understanding Auto-configured Beans
中继续介绍了SpringBoot
自动装配底层实现与Spring Framework
注解@Configuration
和@Conditional
的联系
Under the hood, auto-configuration is implemented with standard
@Configuration
classes. Additional@Conditional
annotations are used to constrain when the auto-configuration should apply. Usually, auto-configuration classes use@ConditionalOnClass
and@ConditionalOnMissingBean
annotations. This ensures that auto-configuration applies only when relevant classes are found and when you have not declared your own@Configuration
.
文中提到的 @ConditionalOnClass
and @ConditionalOnMissingBean
是最常见的注解,顾名思义,当@ConditionalOnClass
标注在@Configuration
类上时,当且仅当目标类存在于ClassPath
下是才予以装配。
例如:redis
自动装配类RedisAutoConfiguration
判断条件:
- RedisOperations.class是否存在
- 如果pom中引入了
spring-boot-starter-redis
,就会显示存在这个类
- 如果pom中引入了
- Spring Bean容器中是否存在
redisTemplate
- 如果不存在则使用默认的自动配置
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
...
spring-boot-autoconfigure
是spring Boot
核心模块(jar),其中提供了大量的内建自动装配@Configurtation
类,它们统一存放在org.springframework.boot.autoconfigure
包或者子包下面,同时这些类均配置在META-INF/spring.factories资源中:
...
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
...
创建自动配置类
1.启动类
package com.huajie.springboot.sample.spring.application.bootstrap;
...
@EnableAutoConfiguration
public class AppBootstrap {
public static void main(String[] args) {
SpringApplication.run(AppBootstrap.class, args);
}
}
2.增加配置类WebConfiguration
package com.huajie.springboot.sample.spring.application.config;
...
@Configuration
public class WebConfiguration {
@Bean
public RouterFunction<ServerResponse> helloWorld() {
return route(GET("/hello-world"),
request -> ok().body(Mono.just("Hello,World"), String.class)
);
}
@EventListener(WebServerInitializedEvent.class)
public void onWebServerReady(WebServerInitializedEvent event) {
System.out.println("当前 WebServer 实现类为:" + event.getWebServer().getClass().getName());
}
}
3.创建自动配置类WebAutoConfiguration
,并使用@Import
注解导入WebConfiguration
类
package com.huajie.springboot.sample.spring.application.autoconfig;
...
/**
* Web 自动装配类
*/
@Configuration
@Import(WebConfiguration.class)
public class WebAutoConfiguration {
}
4.在项目src/main/resource
目录下新建META-INF/spring.factories
# 自动装配
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.huajie.springboot.sample.spring.application.autoconfig.WebAutoConfiguration
测试:
启动AppBootstrap
类,在没有使用@ComponentScan
的情况下可以装配到WebConfiguration
类
浏览器输入
http://127.0.0.1:8080/hello-world
参考
- 《Spring Boot 编程思想》-小马哥