本文最后更新于 2025年7月13日 中午
Start Up 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @RestController @RequestMapping("/Hello") public class HelloController { @RequestMapping("/world") public String Hello () { return "hello world" ; } }@SpringBootApplication public class SpringwebApplication { public static void main (String[] args) { SpringApplication app = new SpringApplication (SpringwebApplication.class); app.run(args); } }
Spring Boot 会从application.properties 中加载配置
配置加载顺序 1 2 3 4 5 6 1. 根目录 application.propertites2. 根目录的config文件 .\\config\\application.propertites3. 项目根目录 root\\application.propertites4. 项目根目录的config文件 root\\config\\application.propertites5. 直接使用 --spring.config.location = path 作为输入参数 class path 查询6. 直接传入物理配置路径
环境配置 通过spring.profiles.active = prod(则会加载一个application-prod文件)
1 2 application-dev.propertites application-prod.propertites
批量注入属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 application.properties : user.name = codfish user.age = 18 @Component @ConfigurationProperties(prefix="user") public class User { private String username ; private Integer age ; public String getUsername () { return username ; } public void setUsername (String username) { this .username = username; } public Integer getAge () { return age ; } public void setAge (Integer age) { this .age = age ; } }@SpringBootTest class SpringwebApplicationTests { @Autowired private User user ; @Test void contextLoads () { System.out.println( user); } }
添加属性自动提示
添加 spring-boot-configuration-processor 依赖
使能注解处理器(idea)
属性注入的两种方式 properties
1 2 3 4 5 6 7 8 9 server.port =8083 user.username = codfishuser.age = 8 user.birthday = 2019 /05 /01 user.hobbies = [a,v,c] user.girlfriend.3 =cat //字典或自定义类需要使用.key 来进行赋值user.girlfriend.8 =liuser.address.id =3 user.address.desc =cheng hua avenue
yml
1 2 3 4 5 6 7 8 9 10 11 12 User: username: codfish age: 18 hobbies: - 1 - 2 - 3 girl-friend: 1: zhao 2: li address: {id: 1 , desc: zhongguancun } birthday: 2020 /08/06
可以使用 ${} 在配置文件中进行占位
1 2 3 4 5 6 7 8 9 ${random.value} ${random.int} ${random.int[1024,65536]} 范围 ${random.int(2)} 范围 @Validated 进行数据校验 对 不能为空的值 指定为NOT NULL
Spring Boot自动装配过程 SpringBootApplication 从主程序开始
1 2 3 4 5 6 7 @SpringBootApplication class SpringBootwebApplication { public static void main (String[] args) { SpringApplication app = new SpringApplication (SpringBootwebApplication.class); app.run(args); } }
@SpringBootApplication 是一个合成注解
其中包含了 一些元注解
@Target({ElementType.TYPE}) //元注解 定义注解使用的位置,这里声明了可以在类位置进行注解 @Retention(RetentionPolicy.RUNTIME) // 元注解:指定注解的生命周期。RetentionPolicy.RUNTIME 表示注解在运行时仍然可用,JVM 会保留它,可通过反射读取。 @Documented // 元注解:表示该注解会被包含在 Javadoc 文档中。 @Inherited // 元注解:表示子类可以继承父类上标注的注解(仅限 class 类型注解,对方法和字段无效)。
Spring 提供的注解
@SpringBootConfiguration // @Configuration 的派生注解,标识该类是 Spring Boot 应用的配置类入口。 @EnableAutoConfiguration // 启用 Spring Boot 的自动配置机制,根据类路径中的依赖及配置自动装配 Spring Bean。 @ComponentScan(
// 扫描指定包路径下的组件(如 @Component、@Service、@Controller 等), // excludeFilters 用于排除指定类型的类(如自动配置类、用户配置类),防止重复装配或冲突。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ) , @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} ) } )public @interface SpringBootApplication { ... }
通过 EnableAutoConfiguration 自动装配支持自动装配的配置类
通过 ComponentScan 加载剔除了用户配置类和自动装配类的其他类。
EnableAutoConfiguration EnableAutoConfiguration 注解中提供了两个注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration" ; Class<?>[] exclude() default {}; String[] excludeName() default {}; }
AutoConfigurationPackage autoConfigurationPackage 是一个声明为抽象类的静态工具类。它主要负责对基础java类路径的检索,并且提供方法将factories中的类描述信息注册到Beandefinition中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public abstract class AutoConfigurationPackages { private static final Log logger = LogFactory.getLog(AutoConfigurationPackages.class); private static final String BEAN = AutoConfigurationPackages.class.getName(); public static boolean has (BeanFactory beanFactory) { } public static List<String> get (BeanFactory beanFactory) { } static final class BasePackages { ... List<String> get () { if (!this .loggedBasePackageInfo) { if (this .packages.isEmpty()) { if (AutoConfigurationPackages.logger.isWarnEnabled()) { AutoConfigurationPackages.logger.warn("@EnableAutoConfiguration was declared on a class in the default package. Automatic @Repository and @Entity scanning is not enabled." ); } } else if (AutoConfigurationPackages.logger.isDebugEnabled()) { String packageNames = StringUtils.collectionToCommaDelimitedString(this .packages); AutoConfigurationPackages.logger.debug("@EnableAutoConfiguration was declared on a class in the package '" + packageNames + "'. Automatic @Repository and @Entity scanning is enabled." ); } this .loggedBasePackageInfo = true ; } return this .packages; } } }
AutoConfigurationImportSelector autoconfigurationimportselector 是用于执行自动装配的核心类,它实现了一个延迟注册方法。
保证了整体的 Bean注入装配过程
1 2 3 4 5 6 7 8 9 @SpringBootApplication ↓@ComponentScan 扫描用户自定义类 ↓@EnableAutoConfiguration 加载自动配置类 ↓ 注册 BeanDefinition(用户 + 自动配置类) ↓ 创建 Bean(实例化 → 注入依赖 → 初始化)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class AutoConfigurationImportSelector implements DeferredImportSelector ... { public Class<? extends DeferredImportSelector .Group> getImportGroup() { return AutoConfigurationGroup.class; } private static final class AutoConfigurationGroup implements DeferredImportSelector .Group{ public void process (AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) } } protected AutoConfigurationEntry getAutoConfigurationEntry (AnnotationMetadata annotationMetadata) { if (!this .isEnabled(annotationMetadata)) { return EMPTY_ENTRY; AnnotationAttributes attributes = this .getAttributes(annotationMetadata); List<String> configurations = this .getCandidateConfigurations(annotationMetadata, attributes); configurations = this .<String>removeDuplicates(configurations); Set<String> exclusions = this .getExclusions(annotationMetadata, attributes); this .checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = this .getConfigurationClassFilter().filter(configurations); this .fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry (configurations, exclusions); } }
SpringBoot 的自动装配过程
对于常规配置类,直接进行Bean注册过程;
对于自动配置类先进行延迟处理;
待所有常规配置类注册完毕后,进行自动配置类的注册。之后进行Bean 的创建
Spring3 之后 使用类似org.springframework.boot.autoconfigure.AutoConfiguration.import 通过spi的方式 进行类的查询和加载
自动配置类加载
1 2 3 4 5 6 @Configuration(proxyBeanMethod=false) (允许类对bean进行代理)@EnableConfigurationProperties(ServerPropertites.class ) @ConditionalOnWebApplication(type= ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass(CharacterEncodingFilter.class) @ConditionalOnProperty(prefix="server.servlet.encoding",value="enable",matchIfMissing=True) 条件满足时 加载组件