springboot目录及自动装配的实现原理

目录结构:

 static : 静态资源(js css 图片 音频  视频)

templates : 模板文件 (模板引擎freemarker ,  thymeleaf ; 默认不支持JSP)

application.properties : 配置文件

spring boot 内置了tomcat ,并且不需要打成war包再执行。

可以在application.properties中,对端口号等服务器端信息进行配置。

spring boot将各个应用/第三方框架,设置成一个个“场景” starter

选择后,spring boot会将该场景所需要的所有依赖自动注入。

例如 选择“web”,spring boot就会将web相关的依赖(tomcat json等)全部引入本项目。

@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) })
@ConfigurationPropertiesScan
public @interface SpringBootApplication {

@SpringBootApplication : spring boot的主配置类

该注解包含 : 

@SpringBootConfiguration : 包含@Configuration,表示“配置类” : 

1、表示该类是一个配置类

2、加了@Configuration注解的类,会自动纳入spring容器中(类似spring中的@Component)

@EnableAutoConfiguration : 使用spring boot可以自动配置。

使用约定优于配置的原则 ,也就是说,如果不配置的情况下,会使用默认值来处理,因为绝大部分的配置都有默认值,所以可以完全不需要配置。

可以找到@SpringBootApplication所在类的包,作用: 就会将该包及所有的子包,全部纳入spring容器。

springboot会根据META-INF/spring.factories找到相应的第三方依赖,并将这些依赖引入本项目。

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

该文件在:

/home/zyf/maven_repository/org/springframework/boot/spring-boot-autoconfigure/2.2.0.M2/spring-boot-autoconfigure-2.2.0.M2-sources.jar

的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,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\

...

总结:

编写项目时,一般会对自己写的类,以及第三方依赖 进行配置,但是spring boot 可以自动进行配置:

a、自己写的类,spring boot 通过@SpringBootConfiguration自动配置。

b、第三方依赖 通过 spring-boot-autoconfigure-2.2.0.M2-sources.jar 包中的META-INF/spring.factories进行声明,然后通过 @EnableAutoConfiguration 开启使用。

 spring-boot-autoconfigure-2.2.0.M2-sources.jar 包中包含了J2EE整合体系中需要的依赖。

c、自动装配的实现

    查看 org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration源码:

当中:

@Configuration 标识该类为一个配置类、将此类纳主SRPING IOC容器

@EnableConfigurationProperties(HttpProperties.class) : 通过HttpProperties将默认编码设置 为utf-8;

HttpProperties.java : private final Encoding encoding = new Encoding();

Encoding.java : public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

即自动装配为utf-8。

@EnableConfigurationProperties提供了prefix + 属性名 的方式 供我们修改编码。

如果需要修改默认值,在application.properties中加入:

spring.http.encoding.charset=ISO-8859-1

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled",
matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

@ConditionalOnXXX说明 :

@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)

含义:当属性spring.http.encoding满足要求时,此条件成立:要求spring.http.encoding.enabled =XXX , 如果没有配置,则此条件成立。也就是说,如果开发者没有配置相关的属性时,就使用默认的设置。否则使用开发者的配置。

@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) :运行在web应用中,条件成立
@ConditionalOnClass(CharacterEncodingFilter.class)  : 当这个类CharacterEncodingFilter.class存在时条件成立 

即只有当这三个要求都成立时,此类才会生效。

总结:

1、第一个XXXAutoConfiguration 都有许多条件限制@ConditionalOnXXX,当这些条件都满足时,此配置自动装配生效。

我们可以手动的修改自动装配:在XXXProperties文件中 加入 prefix.属性名=value

2、全局配置文件里的KEY,来源于某个Properties中的prefix+属性名

附@ConditionalOn条件注解列表:

@ConditionalOnBean:当容器里有指定Bean的条件下

@ConditionalOnClass:当类路径下有指定类的条件下

@ConditionalOnExpression:基于SpEL表达式作为判断条件

@ConditionalOnJava:基于JV版本作为判断条件

@ConditionalOnJndi:在JNDI存在的条件下差在指定的位置

@ConditionalOnMissingBean:当容器里没有指定Bean的情况下

@ConditionalOnMissingClass:当类路径下没有指定类的条件下

@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下

@ConditionalOnProperty:指定的属性是否有指定的值

@ConditionalOnResource:类路径是否有指定的值

@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean

@ConditionalOnWebApplication:当前项目是Web项目的条件下。

查看spring boot中开启了哪些自动装配,禁止了哪些自动装配:application.properties中 加入 debug=true,执行run as 后,在输出中可以看到:

Positive matches:
-----------------



CodecsAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.http.codec.CodecConfigurer' (OnClassCondition)



CodecsAutoConfiguration.JacksonCodecConfiguration matched:
- @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper' (OnClassCondition)

。。。



Negative matches:
-----------------

ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)

AopAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.aspectj.lang.annotation.Aspect' (OnClassCondition)
。。。

其中:Positive matches:表示spring boot自动开启的装配

         Negative matches:表示spring boot未自动开启的装配

猜你喜欢

转载自blog.csdn.net/zyfzhangyafei/article/details/89736981