Spring Boot中默认会扫描的启动类对应的子包下面的类,但是项目引入的其他包下面的类要加入到IOC中必须要有所说明,以下说到的自动配置就是干这个活的,springboot就会把配置中的类加载到ioc容器中。
(1)自动配置注册文件
从Spring boot2.7开始自动配置注册有了一个比较大的调整,之前都是写在下面 文件中的:
META-INF/spring.factories
格式为: org.springframework.boot.autoconfigure.EnableAutoConfiguration=[XXXConfig,YYYConfig]
自Spring Boot 2.7 起改名了:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
格式也变了,直接每一行是一个自动配置类,比如spring-cloud-netflix-eureka-client-4.0.3.jar 中的该文件内容为:
org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration
org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration
org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration
org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration
org.springframework.cloud.netflix.eureka.reactive.EurekaReactiveDiscoveryClientConfiguration
org.springframework.cloud.netflix.eureka.loadbalancer.LoadBalancerEurekaAutoConfiguration
(2)注解(@AutoConfiguration)
自Spring Boot 2.7 起新增了一个自动配置注解 @AutoConfiguration,用来代替之前的 @Configuration,用于标识新自动配置注册文件中的顶级自动配置类,由 @AutoConfiguration 注解嵌套、导入进来的其他配置类可以继续使用 @Configuration 注解。
另外,为方便起见,@AutoConfiguration 注解还支持 after, afterNames, before 和 beforeNames 属性进行自动配置排序,用于代替之前的 @AutoConfigureAfter 和 @AutoConfigureBefore 注解。
这个注解可以说更加细分了吧,自动配置专用注解,用专门的注解来干专门的事。
自动配置生效有很多源注解:
@ConditionalOnBean 配置的bean存在时,才会创建这个bean;
@ConditionalOnMissingBean 配置的bean不存在时,才会创建这个bean;
@ConditionalOnClass Classpath中存在配置的类,才会创建这个bean;
@ConditionalOnMissingClasses Classpath中不存在配置的类,才会创建这个bean;
@ConditionalOnJava JDK版本在范围以内,才会创建这个bean;
@ConditionalOnExpression 指定的SpEL表达式结果为true,才会创建这个bean;
@ConditionalOnWebApplication 是一个WEB应用程序,才会创建这个bean;
@ConditionalOnNotWebApplication 不是一个WEB应用程序,才会创建这个bean;
@ConditionalOnCloudPlatform 仅当我们在某个云平台上运行时才加载bean:
@ConditionalOnJndi("java:comp/env/ejb/myEJB") 仅当通过JNDI提供某个资源时才加载bean:
@ConditionalOnProperty(prefix = "notification", name = "service")仅在存在环境属性()且具有特定值的情况下才启用Bean注册,默认情况下,必须定义指定的属性,并且不等于false。
@ConditionalOnResource(resources="classpath:shiro.ini") 当指定的资源文件出现在classpath中生效
(3)配置提示功能
如下3个文件都是用于配置提示:
spring-configuration-metadata.json
additional-spring-configuration-metadata.json
spring-autoconfigure-metadata.properties
其中spring-configuration-metadata.json和spring-autoconfigure-metadata.properties是插件生成的,additional-spring-configuration-metadata.json一般没额外的补充信息需求的话也不用写。
自定义配置提示只需要在项目中引入如下依赖即可:
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-autoconfigureartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-autoconfigure-processorartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-configuration-processorartifactId>
optional>trueoptional>
dependency>
(4)spring-boot-starter-xxx.jar为什么都是空项目?
以spring-cloud-starter-loadbalancer-4.0.4.jar为例,本身是一个空项目,只是依赖项目spring-cloud-loadbalancer-4.0.4.jar。
在spring-cloud-loadbalancer-4.0.4.jar中的关键自动配置部分:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,
给出了自动配置的信息。
之所以拆分为一个空工程和一个配置工程的原因,只能先猜测一下。
(1)有可能是空的spring-cloud-starter-xxx工程可以有比较灵活的依赖,不一定要和spring-cloud-xxx完全绑死,除了依赖spring-cloud-xxx外还可以依赖其他工程。
但是spring-boot-starter-3.1.4.jar和spring-boot-start-cache-3.1.4.jar和spring-boot-start-freemarker-3.1.4.jar 这些都是空工程,连依赖都没有,根本体现不出来上面的意义啊。
(2)也可能是有名字好理解一点
如果是这个理由,直接把spring-cloud-xxx命名为spring-cloud-starter-xxx,用一个工程不是更好吗,感觉牵强得很。