系统要求
Maven配置文件
新添内容:
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
需求:浏览发送/hello请求,响应 “Hello,Spring Boot 2”创建maven工程
父:spring-boot-starter-parent
引入依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
创建主程序
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
编写业务
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String handle01(){
return "Hello, Spring Boot 2!";
}
}
运行&测试
运行MainApplication类
浏览器输入http://localhost:8080/hello,将会输出Hello!。
设置配置
maven工程的resource文件夹中创建application.properties文件。
/# 设置端口号
server.port=8888
更多配置信息
打包部署
之前是打成war包,然后放到tomcat中运行。
现在: 在pom.xml添加
<!-- 这个插件,可以将应用打包成一个可执行的jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
在IDEA的Maven插件上点击运行 clean 、package,把helloworld工程项目的打包成jar包,
打包好的 jar 包被生成在helloworld工程项目的target文件夹内。
用cmd运行java -jar boot-01-helloworld-1.0-SNAPSHOT.jar,既可以运行helloworld工程项目。
将jar包直接在目标服务器执行即可。
1、引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2、创建主程序
/**
* @SpringBootApplication 标志这个一个Springboot应用
*/
@SpringBootApplication
@Slf4j
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class,args);
log.info("系统正常启动");
}
}
3、编写业务
@RestController //@RestController = @Controller + @ResponseBody
public class HelloController {
@RequestMapping("/hello")
public String handle01(){
return "hello";
}
}
4、测试
直接运行Main
5、简化配置
application.properties:
server.port=8888
6、简化部署
<!-- 这个插件,可以将应用打包成一个可执行的jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
把项目打成jar 包,直接在目标服务器执行就行。
管理依赖的版本号,默认引入的引来可以不写版本号,有默认值,当然也可以写。
依赖管理
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
上面项目的父项目如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
它几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.4.RELEASE</version> <scope>compile</scope> </dependency>
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
IDEA快捷键:
option + command + U
:以图的方式显示项目中依赖之间的关系。引入spring-boot-starter-web依赖,会默认包含:
spring-boot-starter-tomcat、spring-web、spring-webmvc
**1.3.1、**自动配好Tomcat
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>2.3.4.RELEASE</version> <scope>compile</scope> </dependency>
**1.3.2、**自动配好SpringMVC
**1.3.3、**自动配好Web常用功能:字符编码问题
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
**1.3.4、**默认的包结构
主程序(MainApplication)所在包及其下面的所有子包里面的组件都会被默认扫描进来
无需以前的包扫描配置
想要改变扫描路径
@SpringBootApplication(scanBasePackages=“com.lun”)
或者
@ComponentScan 指定扫描路径
@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.lun")
**1.3.4、**各种配置拥有默认值
MultipartProperties
Full模式与Lite模式
/**
* 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
* 2、配置类本身也是组件
* 3、proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true)(保证每个@Bean方法被调用多少次返回的组件都是单实例的)(默认)
* Lite(proxyBeanMethods = false)(每个@Bean方法被调用多少次返回的组件都是新创建的)
*/
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
/**
* Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
* @return
*/
@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Pet组件
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
public class MainApplication {
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//3、从容器中获取组件
Pet tom01 = run.getBean("tom", Pet.class);
Pet tom02 = run.getBean("tom", Pet.class);
System.out.println("组件:"+(tom01 == tom02));
//4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
MyConfig bean = run.getBean(MyConfig.class);
System.out.println(bean);
//如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
//保持组件单实例
User user = bean.user01();
User user1 = bean.user01();
System.out.println(user == user1);
User user01 = run.getBean("user01", User.class);
Pet tom = run.getBean("tom", Pet.class);//用户获取的pet是容器中唯一的
System.out.println("用户的宠物:"+(user01.getPet() == tom));//true
}
}
**注意:**springboot使用 配置类 代替 bean配置文件
<bean id="user01" class="com.rc.spring.boot.bean.User">
<property name="name" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
@Configuration //告诉spring容器这是一个配置类,==配置文件
public class MyConfig {
//给容器添加组件,方法名为组件id,返回类型为组件类型,返回的值为组件在容器中的实例。
@Bean
public User user01(){
return new User("zhangsna",18);
}
}
最佳实战
配置类 组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
因为使用Lite模式,每次从容器获取组件时不会在容器中再执行判断操作,判断组件是否存在。
配置类 组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式(默认)
容器中bean相互依赖时,full模式能保证调用的依赖组件是同一个。
@Import({User.class, DBHelper.class})
@Configuration
public class MyConfig {
@Bean
public User user01(){
return new User("zhangsna",18);
}
@Bean("cat02")
public Pet cat(){
return new Pet("tomcat");
}
}
@SpringBootApplication(scanBasePackages = "com.rc.spring.boot")
@Slf4j
public class MainApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MainApplication.class, args);
String[] beanNamesForType = context.getBeanNamesForType(User.class);
for (String s : beanNamesForType) {
System.out.println(s);
}
//com.rc.spring.boot.bean.User
//user01
DBHelper bean1 = context.getBean(DBHelper.class);
System.out.println(bean1);//ch.qos.logback.classic.db.DBHelper@61942c1
}
}
举例:
用@ConditionalOnBean举例说明,user有一只猫,即存在依赖关系,故需要实现当容器中没有猫组件时,user组件也不注册到容器中。
@Configuration(proxyBeanMethods = false)
public class MyConfig {
//在容器中有tom名字的Bean时,user01的bean才会注册到容器中。否则不会注册
@ConditionalOnBean(name = "tom")
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
zhangsan.setPet(tomcatPet());
return zhangsan;
}
public Pet tom(){
return new Pet("tomcat");
}
}
**@ConditionOnBeanname="tom")标注在类上:**是说只有在容器中有名字为 tom 的bean时,该类里的所有bean才会生效。否则不生效
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(name = "tom")//有tom名字的Bean时,MyConfig类的Bean才能生效。
public class MyConfig {
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom22")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
boolean tom = run.containsBean("tom");
System.out.println("容器中Tom组件:"+tom);//false
boolean user01 = run.containsBean("user01");
System.out.println("容器中user01组件:"+user01);//true
boolean tom22 = run.containsBean("tom22");
System.out.println("容器中tom22组件:"+tom22);//true
}
比如,正常使用全注解开发后,bean.xml文件的内容已经不使用了,即里面的bean不会注册到容器中。
然而,有些公司以前使用bean.xml文件生成配置bean,当我们想继续复用bean.xml,不想全部改成注解的形式时,可以使用@ImportResource 来让bean.xml 继续生效,保证xml中的bean注册到容器中。
bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans ...">
<bean id="haha" class="com.lun.boot.bean.User">
<property name="name" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
<bean id="hehe" class="com.lun.boot.bean.Pet">
<property name="name" value="tomcat"></property>
</bean>
</beans>
使用:
@Import({User.class, DBHelper.class})
@Configuration //告诉spring容器这是一个配置类,==配置文件
@ConditionalOnMissingBean(name="tom")
@ImportResource("classpath:bean.xml")
public class MyConfig {
}
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
boolean haha = run.containsBean("haha");
boolean hehe = run.containsBean("hehe");
System.out.println("haha:"+haha);//true
System.out.println("hehe:"+hehe);//true
}
只有在容器中的组件,才能拥有springboot 提供的强大功能,即容器提供的强大功能,即才能使用容器里的使用组件。
如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用
传统方法:
public class getProperties {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties pps = new Properties();
pps.load(new FileInputStream("a.properties"));
Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
while(enum1.hasMoreElements()) {
String strKey = (String) enum1.nextElement();
String strValue = pps.getProperty(strKey);
System.out.println(strKey + "=" + strValue);
//封装到JavaBean。
}
}
}
@ConfigurationProperties + @Component
1、配置文件application.properties
mycar.brand=BYD
mycar.price=100000
2、使用@ConfigurationProperties(prefix="mycar")
将 文件内容和 实体 绑定。注意加上@Component表示是容器中组件
@Data
@NoArgsConstructor
@AllArgsConstructor
@ConfigurationProperties(prefix = "mycar")
@Component
public class Car {
String price;
String branch;
}
3、验证
@RestController //@RestController = @Controller + @ResponseBody
public class HelloController {
@Autowired
private Car car;
@RequestMapping("/car")
public Car getCar(){
return car;
}
}
只有在容器中的组件,才会拥有SpringBoot提供的强大功能
@EnableConfigurationProperties + @ConfigurationProperties
一定 在配置类上 写 @EnableConfigurationProperties(Car.class)
开启Car配置绑定功能
把这个Car这个组件自动注册到容器中
在实体类上 @ConfigurationProperties(prefix="mycar")
application.properties
server.port=8888
mycar.branch=bmw
mycar.price=100000
@Import({User.class, DBHelper.class})
@Configuration //告诉spring容器这是一个配置类,==配置文件
@ConditionalOnMissingBean(name="tom")
@ImportResource("classpath:beans.xml")
@EnableConfigurationProperties(Car.class)
public class MyConfig {
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@ConfigurationProperties(prefix = "mycar")
//@Component
public class Car {
String price;
String branch;
}
@SpringbootApplicaion
@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 {
...
}
重点分:
@SpringBootConfiguration
,@EnableAutoConfiguration
,@ComponentScan
。
@Configuration
代表当前是一个配置类。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
指定扫描哪些Spring注解
@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 {};
}
自动配置包,指定了默认的包规则。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class) //给容器中导入一个组件
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
public class AutoConfigurationImportSelector{
@Override
public String[] **selectImports**(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = **getAutoConfigurationEntry(annotationMetadata);**
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected AutoConfigurationEntry **getAutoConfigurationEntry
**(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = **getCandidat**eConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
protected List<String> **getCandidateConfigurations**(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.l**oadFactoryNames(getSpringFactoriesLoaderFactoryClass(),**
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
}
public final class SpringFactoriesLoader {
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> **loadSpringFactories**(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? **classLoader.getResources("META-INF/spring.factories") **: ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类(共127个自动配置类,就是在配置文件里写死的,命名为xxxAutoConfiguration)
利用工厂加载Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
从META-INF/spring.factories位置来加载一个文件。(在我们引入的所有jar包里,有的meta-inf里没有内容,有的有spring.factories)
默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
虽然我们127个场景的所有自动配置启动的时候默认全部加载,但是xxxxAutoConfiguration
按照条件装配规则(@Conditional
),最终会按需配置。
文件里面写死了启动配置类,共127个,springboot一启动就要从容器中加载所有的配置类。
文件位置:weispring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories
如AopAutoConfiguration
类。
按需加载的条件装配:满足条件才能生效。下面aop里面不满足条件,Advice标红不能生效。
8、自动配置【源码分析】-自动配置流程
DispatcherServletAutoConfiguration
的内部DispatcherServletConfiguration
:
方法会从容器中找MultipartResolver类型的解析器,找到后赋值给resolver返回。
@Bean
@ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {
//给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
// Detect if the user has created a MultipartResolver but named it incorrectly
return resolver;//给容器中加入了文件上传解析器;
}
看CacheAutoConfiguration是否生效。
**@ConditionalOnClass(CacheManager.class):**首先找下CacheManager是否存在:双击shift,搜索CacheManager,在spring-context中故存在。
然后查看CacheAspectSupport类型的bean
//查找CacheAspectSupport类型的组件在容器中存在几个
String[] CacheAspectSupport = context.getBeanNamesForType(CacheAspectSupport.class); System.out.println("CacheAspectSupport.length:" + CacheAspectSupport.length); //CacheAspectSupport.length
@Configuration(proxyBeanMethods = false)
**@ConditionalOnClass(CacheManager.class)**
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureAfter({ CouchbaseDataAutoConfiguration.class, HazelcastAutoConfiguration.class,
HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class })
public class **CacheAutoConfiguration** {
看DispatcherServletAutoConfiguration是否生效。
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(DispatcherServlet.class) @AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
}
@ConditionalOnClass(DispatcherServlet.class)**:**首先找下DispatcherServlet是否存在:双击shift,搜索DispatcherServlet,在spring-web中故存在。
看 DispatcherServletAutoConfiguration中的内部类DispatcherServletConfiguration是否生效。
@Configuration(proxyBeanMethods = false)
@Conditional(DefaultDispatcherServletCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
protected static class **DispatcherServletConfiguration** {
@ConditionalOnClass(ServletRegistration.class):首先找下ServletRegistration是否存在:双击shift,搜索ServletRegistration,在tomcat-embed-core中故存在。
@EnableConfigurationProperties(WebMvcProperties.class):开启类WebMvcProperties与配置文件的绑定,即配置文件以spring.mvc为前缀的配置 可以修改 该类中的属性值。然后将WebMvcProperties放到容器中。
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
private DefaultMessageCodesResolver.Format messageCodesResolverFormat;
private Locale locale;
private LocaleResolver localeResolver = LocaleResolver.ACCEPT_HEADER;
}
//查找 WebMvcProperties 类型的组件在容器中存在几个
String[] WebMvcProperties = context.getBeanNamesForType(WebMvcProperties.class);
System.out.println("WebMvcProperties.length:" + WebMvcProperties.length);
//WebMvcProperties.length:1
HttpEncodingAutoConfiguration:解决请求编码问题,编码的自动解析,解析中文乱码。
如果用户没配置,则系统默认配置,如果用户自己配置了就用用户的。
@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(ServerProperties.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass(CharacterEncodingFilter.class) @ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
}
**约定大于配置:**SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先。约定是指用户手动配置的,配置是指Springboot默认配置的。
SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration。
每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。(xxxxProperties里面读取,xxxProperties和配置文件进行了绑定)。
生效的配置类就会给容器中装配很多组件。
只要容器中有这些组件,相当于这些功能就有了。
定制化配置
方法1:用户直接自己@Bean替换底层的组件
方法2:在配置文件修改值,用户去看这个组件是获取的配置文件什么值就去修改。
xxxxxAutoConfiguration —> 组件 —> 组件从 xxxxProperties里面拿值 ----> application.properties
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/mingyuli/article/details/120920899
内容来源于网络,如有侵权,请联系作者删除!