基于上一节开始说。如图,新建项目后会自动创建一个启动类
可以看出来只有一个注解和调用了一个方法,这节主要讲注解(java注解)所以这是关注点@SpringBootApplication
实际注解只有三个:
@SpringBootConfiguration:Spring Boot配置声明
@EnableAutoConfiguration:开启自动配置
@ComponentScan:组件扫描(自动扫描该组件)
@EnableAutoConfiguration
@AutoConfigurationPackage:自动配置包,实际是自动扫描并配置我们写的类
@Import({AutoConfigurationImportSelector.class}):Spring提供的注解,导入Bean或类到当前类中,实际是根据POX文件的配置自动配置官方定义的类
@AutoConfigurationPackage
结论:@AutoConfigurationPackage会自动扫描该注解同包及子包中的所有注解
@Import({AutoConfigurationImportSelector.class})
结论:@Import({AutoConfigurationImportSelector.class})会自动扫描autoconfigure包下META-INF/spring.factories文件中的EnableAutoConfiguration下的配置,然后把在POX文件中添加过的数据及关联数据自动配置
@Conditional
@Conditional是由Spring 4提供的一个新特性,用于根据特定条件来控制Bean的创建行为。而在我们开发基于Spring的应用的时候,难免会需要根据条件来注册Bean
例如,你想要根据不同的运行环境,来让Spring注册对应环境的数据源Bean,对于这种简单的情况,完全可以使用@Profile注解实现,就像下面代码所示:
剩下只需要设置对应的Profile属性即可,设置方法有如下三种:
- 通过
context.getEnvironment().setActiveProfiles("PROD")
来设置Profile属性 - 通过设定jvm的
spring.profiles.active
参数来设置环境(Spring Boot中可以直接在properties
配置文件中设置该属性) - 过在DispatcherServlet的初始参数中设置
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>spring.profiles.active</param-name> <param-value>PROD</param-value> </init-param> </servlet>
但这种方法只局限于简单的情况,而且通过源码我们可以发现@Profile自身也使用了@Conditional注解
在业务复杂的情况下,显然需要使用到@Conditional注解来提供更加灵活的条件判断,例如以下几个判断条件
- 在类路径中是否存在这样的一个类
- 在Spring容器中是否已经注册了某种类型的Bean(如未注册,我们可以让其自动注册到容器中,上一条同理)
- 一个文件是否在特定的位置上
- 一个特定的系统属性是否存在
- 在Spring的配置文件中是否设置了某个特定的值
举个栗子,假设我们有两个基于不同数据库实现的DAO,其中MysqlUser与MySql进行连接,MongoDBUser与MongoDB进行连接。现在,我们有了一个需求,需要根据命令行传入的系统参数来注册对应的User,就像java -jar app.jar -DdbType=mysql
会注册MysqlUser,而java -jar app.jar -DdbType=mongodb
则会注册MongoUser(也可以在properties中直接设置)。使用@Conditional可以很轻松地实现这个功能,仅仅需要在你自定义的条件类中去实现Condition接口,让我们来看下面的代码。(以下案例来自:https://dzone.com/articles/how-springboot-autoconfiguration-magic-works)