@SpringBootApplication注解源码分析
配置类
自动配置
组件扫描 扫描其子包下的配置类
@SpringBootConfiguration
可以自定义配置类将其加入到IOC容器中(一般在启动类里(@SpringBootApplication已有)使用 只是用一次)
@Configuration 配置类详解 (spring提供的类)
针对自己定义的类要加到IOC可以使用@Configuration 相当于配置文件《bean》《bean/》
//如何使用
@Configuration
public class MyConfig {
@Bean //必须的加
public MyConfigBean myConfigBean() {
return new MyConfigBean();
}
}
@Configuration使用@Component进行元注释,因此@Configuration类是组件扫描的候选类(通常使用Spring XML的元素),因此也可以像使用任何常规的@Component一样利用@Autowired/@Inject。特别是,如果有一个单独的构造函数存在,自动装配语义将被透明地应用于该构造函数:
@Configuration
public class AppConfig {
//z自定义bean
private final SomeBean someBean;
//只有一个构造方法直接可以将其注入IOC容器中
public AppConfig(SomeBean someBean) {
this.someBean = someBean;
}
// @Bean definition using "SomeBean"
}
外部化的值可以通过注入Spring org.springframe .core.env来查找。例如,使用@Autowired注解:
@Configuration
public class AppConfig {
//可以使用@Autowired 注入
@Autowired Environment env;
@Bean
public MyBean myBean() {
MyBean myBean = new MyBean();
//getProperty("bean.name")获取配置文件的值
myBean.setName(env.getProperty("bean.name"));
return myBean;
}
}
通过环境解析的属性驻留在一个或多个“属性源”对象中,而@Configuration类可以使用@PropertySource注释将属性源贡献给环境对象:
@Configuration
//使用该注解 就可以到该路径去寻找属性值
@PropertySource("classpath:/com/acme/app.properties")
public class AppConfig {
@Inject Environment env;
@Bean
public MyBean myBean() {
return new MyBean(env.getProperty("bean.name"));
}
}
外部化的值可以使用@Value注释注入到@Configuration类中:
@Configuration
//ioc扫描指定的配置文件
@PropertySource("classpath:/com/acme/app.properties")
public class AppConfig {
//获取app.properties配置文件中“bean.name” 对应的值
@Value("${bean.name}")
String beanName;
@Bean
public MyBean myBean() {
return new MyBean(beanName);
}
}
这种方法常与Spring的PropertySourcesPlaceholderConfigurer一起使用,可以自动启用XML配置通过<上下文:property-placeholder / >或@ configuration类中显式地通过一个专门的静态@ bean方法(见“注BeanFactoryPostProcessor-returning @ bean方法”@ bean的javadocs详情)。但是请注意,只有在需要自定义配置(如占位符语法等)时,才需要通过静态@Bean方法显式注册PropertySourcesPlaceholderConfigurer。具体地说,如果没有bean后处理器(例如PropertySourcesPlaceholderConfigurer)为ApplicationContext注册了嵌入式值解析器,**Spring将注册一个默认的嵌入式值解析器,它根据环境中注册的属性源解析占位符(springboot在加载的时候会将配置文件都加载进去)**参
@Import
@Configuration类可以使用@Import注释组成,类似于在Spring XML中的工作方式。因为@Configuration对象是作为容器中的Spring bean来管理的,所以导入的配置可能会被注入——例如,通过构造函数注入:
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource() {
// instantiate, configure and return DataSource
}
}
@Configuration //类似总配置类
//将DatabaseConfig 加进来
@Import(DatabaseConfig.class)
public class AppConfig {
private final DatabaseConfig dataConfig;
public AppConfig(DatabaseConfig dataConfig) {
this.dataConfig = dataConfig;
}
@Bean
public MyBean myBean() {
// reference the dataSource() bean method
return new MyBean(dataConfig.dataSource());
}
}
现在AppConfig和导入的DatabaseConfig都可以通过在Spring上下文中注册AppConfig来启动:
//启动总配置类 自配置类也被加入到IOC
new AnnotationConfigApplicationContext(AppConfig.class);
@Profile注释(区分环境的)
@Configuration类可能被标记为@Profile注释,以指示只有在给定的配置文件或配置文件处于活动状态时才应该处理它们:
@Profile("development")
@Configuration
public class EmbeddedDatabaseConfig {
@Bean
public DataSource dataSource() {
// instantiate, configure and return embedded DataSource
}
}
@Profile("production")
@Configuration
public class ProductionDatabaseConfig {
@Bean
public DataSource dataSource() {
// instantiate, configure and return production DataSource
}
}
或者,您也可以在@Bean方法级别声明配置文件条件——例如,对于同一个配置类中的可选bean变体:
@Configuration
public class ProfileDatabaseConfig {
@Bean("dataSource")
@Profile("development")
public DataSource embeddedDatabase() { ... }
@Bean("dataSource")
@Profile("production")
public DataSource productionDatabase() { ... }
}
使用嵌套的@Configuration类
@Configuration类可以相互嵌套,如下所示:
@Configuration
public class AppConfig {
@Inject DataSource dataSource;
@Bean
public MyBean myBean() {
return new MyBean(dataSource);
}
@Configuration //嵌套内部类 必须用static修饰
static class DatabaseConfig {
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder().build();
}
}
}
在引导这样的安排时,只需要在应用程序上下文中注册AppConfig。由于是一个嵌套的@Configuration类,DatabaseConfig将自动注册。这就避免了在AppConfig和DatabaseConfig之间的关系已经隐式清晰时需要使用@Import注释。
还请注意,嵌套的@Configuration类可以与@Profile注释一起使用,从而为封闭的@Configuration类提供相同bean的两个选项(区分两个不同的开发环境时 共用一个嵌套bean),效果很好。
配置延迟加载
默认情况下,@Bean方法将在容器引导时都是立即实例化。为了避免这种情况,可以将@Configuration与@Lazy注释结合使用,以指示类中声明的所有@Bean方法在默认情况下都是惰性初始化(延迟加载 用的时候初始化不用就不初始化)的。注意,@Lazy也可以用于单独的@Bean方法
编写@Configuration类时的约束
- 配置类必须以类的形式提供(即不作为从工厂方法返回的实例),允许通过生成的子类进行运行时增强。
- 配置类必须是非final的。
- 配置类必须是非本地的(即不能在方法中声明)。
- 任何嵌套的配置类都必须声明为静态的。
@Bean方法可能不会创建更多的配置类(任何这样的实例都将被视为普通bean,它们的配置注释仍然不会被检测到)。
@EnableAutoConfiguration详解 自动配置
- 启用Spring应用程序上下文的自动配置,尝试猜测和配置您可能需要的bean。自动配置类通常基于类路径(classpath)和自定义的bean来应用的。例如,如果您的类路径中有tomcat-embedde .jar,那么您可能需TomcatServletWebServerFactory(除非您已经定义了自己的ServletWebServerFactorybean)。
- 在使用SpringBootApplication注解时,上下文的自动配置是自动启用的,因此添加这个@EnableAutoConfiguration不会产生额外的影响。
- 自动配置试图尽可能地智能化,并且在您定义更多自己的配置时将会后退。您总是可以手动排除exclude()您从不希望应用的任何配置(如果您没有访问它们的权限,则使用exclude())。您还可以通过spring.autoconfigure排除它们。排除属性。总是在注册了用户定义的bean注册好之后,再应用自动配置。
- 使用@EnableAutoConfiguration注释的类包(通常通过@SpringBootApplication)具有特定的意义,通常用作“默认”。例如,它将在扫描@Entity类时使用。通常建议将@EnableAutoConfiguration(如果不使用@SpringBootApplication)放在根包中,以便搜索所有子包和类。
- 自动配置类是常规的Spring配置bean。它们是使用SpringFactoriesLoader机制定位的(针对这个类进行键控)。通常,自动配置bean是@Conditional (条件注解)bean(通常使用@ConditionalOnClass和@ConditionalOnMissingBean注释)。
@AutoConfigurationPackage 详解
表示了这个包包含了的类应该注册到AutoConfigurationPackages(springboot提供的一个自动配置的类)
AutoConfigurationImportSelector
处理自动配置。如果需要自定义的@EnableAutoConfiguration变量,也可以子类化该类。
@ComponentScan 组件扫描
配置组件扫描指令以与@Configuration类一起使用。提供与Spring XML的元素并行的支持。
可以指定basepackageclass或basePackages(或其别名值)来定义需要扫描的特定包,此时必须和@Configuration联合起来使用才行。如果没有定义特定的包,将对声明此注释的类的子包进行扫描。(springBootApplication启动类包开始扫描)可以将添加该注解的类和平常所熟悉的注解 比如@Controller,@Service,@Repository, @Component 将一个类注入到IOC容器中
这里所说的特定注解就是指 我们
SpringApplication 启动类详解(springboot提供)
该类用来引导和启动Spring 可用于从Java mian方法来启动应用程序。默认情况下,类将执行以下步骤来引导应用程序:
- 创建一个适当的ApplicationContext实例(取决于您的类路径)
- 注册一个CommandLinePropertySource来将命令行参数公开为Spring属性
- 刷新应用程序上下文,加载所有单例bean
- 触发任何 CommandLineRunner 命令执行器bean
在大多数情况下,static run(Class,String[])方法可以直接从你的主方法调用,以引导项目的应用程序:
@Configuration
@EnableAutoConfiguration
public class MyApplication {
// ... Bean definitions
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
对于更高级的配置,可以在运行之前创建和定制一个SpringApplication实例:
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
// ... 在这里自定义应用程序设置 application 的各种set方法
application.run(args)
}
SpringApplications可以从各种不同的来源读取bean。一般建议使用单一的@Configuration类来引导你的应用程序(@SpringBootApplication),但是,你也可以设置来源:
- 由AnnotatedBeanDefinitionReader加载的完全限定类名
- 由XmlBeanDefinitionReader加载的XML资源的位置,或者由GroovyBeanDefinitionReader加载的groovy脚本的位置
- 要被ClassPathBeanDefinitionScanner扫描的包的名称
配置属性也绑定到SpringApplication。这使得动态设置SpringApplication属性成为可能,就像其他的资源一样(“spring.main”)。这个标志表示一个web环境(“spring.main.web-application-type=none”)或者关闭这个标志(“spring.main.banner-mode=off”)。