admin管理员组文章数量:1562473
Spring Boot总览
Spring Boot部署方式
- Jar目录结构
- BOOT-INF
- classes
- lib
- META-INF
- maven
- MANIFEST.MF文件
- org\springframework\boot\loader
- BOOT-INF
- War
Spring Boot项目打成WAR包时,WEB-INF/lib-provided目录存放的是provided的JAR文件。
打包成WAR文件是一种兼容措施,既能被WarLauncher启动,又能兼容Servlet容器环境;
War文件通过传统方式部署可在打包是去除嵌入式Web容器
Spring Boot应用使用非传统Web部署时,尽可能的使用JAR归档方式。
嵌入式容器
Web容器
- Tomcat(默认实现)
- Jetty
- Undertow
Reactor Web容器
- Netty Web Server(默认实现)
- 上述三种嵌入式Servlet容器也能作为Reactive Web Server
**Spring Boot Maven插件spring-boot-maven-plugin采用零压缩模式,将应用归档到JAR或WAR文件 **
外部化配置
- 配置文件:application.properties或application.yml
- 环境变量(OS Environment varibales)
- ,命令行(Command line arguments)
命令行优先于配置文件
注解驱动编程
Spring 注解编程模型
- 元注解(Meta-Annotation)
- Spring模式注解(Stereotype-Annotation)
- Spring组合注解(Composed-Annotation)
Spring注解元信息抽象AnnotationMetadata,具体某个注解的“元注解”信息则通过getMetaAnnotationTypes(String)方法查询;
AnnotationMetadata存在两种实现方式:
- 基于ASM的AnnotationMetadataReadingVisitor
- 基于Java反射API的StandardAnnotationMetadata
Spring注解属性抽象AnnotattionAttributes
注解@Indexed
Spring Framework 5.x引入了注解@Indexed,为模式注解添加索引;
使用时需要添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.0.6.RELEASE</version>
<!--不向下传递依赖-->
<optional>true</optional>
</dependency>
当工程打包为JAR或在IDE工具中重新构建后,META-INF/springponents文件将自动生成;当Spring应用上下文执行@ComponentScan扫描时,META-INF/springponents将被CandidateComponentsIndexLoader读取并加载,转化为CandidateComponentsIndex对象,@ComponentScan不在扫描指定的包路径,而是读取CandidateComponentsIndex对象。
Spring注解驱动设计模式
@Enable模块驱动
- 基于"注解驱动"实现@Enable模块
- @Import注解导入@Configuration类
- 基于"接口编程"实现@Enable模块
- @Import注解导入ImportSelector接口实现类
- @Import注解导入ImportBeanDefinitionRegistrar接口实现类
Spring条件装配之Profile
Spring应用有两种Spring Profile配置的选择:
- ConfigurableEnvironment API编码配置
- Java系统属性配置
@Profile条件装配
原理
入口:ClassPathScanningCandidateComponentProvider类
Spring Boot自动装配
@ComponentScan(basePackages="")注解默认只扫描标记此注解的类所在包
- Spring Boot最核心注解@SpringBootApplication
@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#scanBasePackages属性,等同于配置@ComponentScan#basePackages属性
- @EnableAutoConfiguration
- 可在@EnableAutoConfiguration和@SpringBootApplication中选择其一,激活自动装配特性。
- 失效自动装配
- 代码配置方式
- 配置类型安全的属性方法:@EnableAutoConfiguration.exclude();
- 配置排除类名的属性方法:@EnableAutoConfiguration.excludeName();
- 外部化配置方式
- 配置属性:spring.autoconfigure.exclude
- 代码配置方式
Spring Boot 自动装配原理
@EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
public class AutoConfigurationImportSelector
implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
BeanFactoryAware, EnvironmentAware, Ordered {
...
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
//加载自动装配的元信息
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
//获取@EnableAutoConfiguration标出类的元信息
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//读取候选装配组件
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
//1.配置可能出现组件类名重复定义的情况,利用Set不可重复性达到去重的目的
configurations = removeDuplicates(configurations);
//2.获取排除自动装配组件名单
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
//3.检查排除类名集合是否合法
checkExcludedClasses(configurations, exclusions);
//4.将排除集合exclusions从候选自动装配Class名单configurations中移除
configurations.removeAll(exclusions);
//5.移除排除类名单后的configurations配合AutoConfigurationMetadata对象执行过滤操作
//实际作用是过滤META-INF/spring.factories资源中那些当前ClassLoader不存在的Class
//org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
//org.springframework.boot.autoconfigure.condition.OnClassCondition
configurations = filter(configurations, autoConfigurationMetadata);
//自动装配事件
fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
}
...
应用自定义配置Class能够覆盖其自动装配Class
SpringFactoriesLoader是Spring Framework工厂机制的加载器,loadFactoryNames()方法加载META-INF/spring.factories资源内容作为Properties文件读取,合并为Map作为接口的返回值。
Spring Boot条件自动装配
Class条件注解
-
@ConditionalOnClass-当指定类存在时
@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnClassCondition.class) public @interface ConditionalOnClass { Class<?>[] value() default {}; String[] name() default {};//推荐使用,与@ConditionalOnMissingClass中value()属性方法对应,提高代码可读性 }
注意事项
- @ConditionalOnClass#value()属性方法提供“类型安全”的报障,避免在开发过程中出现全类名拼写的低级失误
- value()属性方法用于类的物理位置非常稳定的情况
- name()属性方法多用于三方库或高低版本兼容的场景
- @ConditionalOnClass#value()属性方法提供“类型安全”的报障,避免在开发过程中出现全类名拼写的低级失误
-
@ConditionalOnMissingClass-当指定类缺失时
@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnClassCondition.class) public @interface ConditionalOnMissingClass { String[] value() default {}; }
Bean条件注解
- @ConditionalOnBean
- @ConditionalOnMissingBean
注意事项
- @ConditionalOnBean和@ConditionalOnMissingBean基于BeanDefinition进行名称或类型的匹配
Property条件注解
- @ConditionalOnProperty-属性条件注解
- 属性来源于Spring Eevironment
- Java系统属性和环境变量
- application.propertis文件
Resource条件注解
- @ConditionalOnResource
Web Application条件注解
- @ConditionalOnWebApplication–当前应用是否为Web类型的条件判断注解
- @ConditionalOnNotWebApplication
Spring表达式条件注解
- @ConditionalOnExpression
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnExpressionCondition.class)
public @interface ConditionalOnExpression {
String value() default "true";
}
Spring Boot 推荐书籍《Spring Boot编程思想》(核心篇) 小马哥/著
版权声明:本文标题:初识Spring Boot 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1727467246a1115897.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论