- 依赖管理
- 启动类
- 自定义组件添加
- 注解
- 自动注入属性值
- @ConfigurationProperties+@Component
- @ConfigurationProperties+@EnableConfigurationProperties
- 自动配置原理初探
父项目做依赖管理
spring-boot-starter-parent中spring-boot-dependencies的基本jar包的版本号。我们无需手动输入版本号。除非引入的jar包springboot没有。
- 开发导入项目场景
org.springframework.boot spring-boot-starter 2.3.4.RELEASE compile
我们也可以手动修改版本号,在pom文件中定义
启动类5.1.43
手写启动类:在扫描路径下的注解会自动识别
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
//启动类的注解 等同于
//@SpringBootConfiguration
//@EnableAutoConfiguration
//@ComponentScan("com.atguigu.boot")
//com.atguigu.boot是扫描包的路径
//或者直接用@SpringBootApplication(scanbasePackages="扫描的包")也可以
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
自定义组件添加
- 创建两个实体类:这里相当于是User组件内嵌了Pet
package cn.zjq.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Pet {
String name;
String age;
}
package cn.zjq.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
String name;
String age;
Pet pet;
}
- 创建一个配置类,使用@Configuration
package cn.zjq.bean;
import cn.zjq.pojo.Pet;
import cn.zjq.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBeans {
@Bean("z")
//注入返回一个实体
User user(){
User user = new User();
user.setPet(pet());
return user;
}
@Bean("pet")
Pet pet(){
return new Pet();
}
}
- spring boot2新增的新特性
proxyBeanMethods默认是true,表示bean代理的方法??
举个栗子
写个配置类
@Configuration(proxyBeanMethods = false)
public class MyBeans {
@Bean
//组件的id就是方法名
User user(){
User user = new User();
user.setPet(pet());
return user;
}
@Bean("tomcat")
//也可以这样自定义组件id
Pet pet(){
return new Pet();
}
}
这里proxyBeanMethods的值是flase,代表从容器里多次取出的不是同一个组件,而是直接调用了方法返回一个对象.我们来测试一下.
在主方法中测试
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
User z = run.getBean(User.class);
Pet pet = run.getBean("pet", Pet.class);
System.out.println(pet==z.getPet());//flase
}
}
flase:若组件间无依赖关系用Lite多例模式加速容器启动过程,减少判断,会比较快
true:若配置类组件之间有依赖关系,Full单例模式,方法会被调用得到之前单实例组件,慢
@import({组件的数组})给容器导入组件
@Conditional条件注入:
○ 派生注解:
■ @ConditionalOnBean注解:当容器中存在指定的组件的时候,才会做某些事情
■ @ConditionalOnMissingBean注解:当容器中不存在指定的组件的时候,才会做某些事情
■ @ConditionalOnClass注解:当容器中有某一个类的时候,才会做某些事情
■ @ConditionalOnMissingClass注解:当容器中,没有某一个类的时候,才会做某些事情
■ @ConditionalOnResource注解:当容器中项目的类路径里面存在某些资源的时候,才会做某些事情
■ @ConditionalOnJava注解:是指定的java版本号的时候,才会做某些事情
■ @ConditionalOnWebApplication注解:当我们的应用是一个web应用的时候,才会做某些事情
■ @ConditionalOnNotWebApplication注解:当我们的应用不是一个web应用的时候,才会做某些事情
■ @ConditionalOnProperty注解:当配置文件配置了指定的属性的时候,才会做某些事情
■ @ConditionalOnSingleCandidate注解:指定的组件有一个实例或者有多个实例一个主实例的时候,才会做某些事情
■ …
■
@Configuration()
public class MyBeans {
@ConditionalOnBean(name = "pet")
//若没有name为pet的组件user组件也不注入
@Bean
User user(){
User user = new User();
user.setPet(pet());
return user;
}
// @Bean
Pet pet(){
return new Pet();
}
}
Boolean z = run.containsBean("user");
//flase
@importResource:通过配置文件导入组件
@Configuration
@importResource("classpath:bean.xml")
public class MyBeans {
}
bean.xml
boolean haha = run.containsBean("haha");
//true
boolean hehe = run.containsBean("hehe");
//true
自动注入属性值
实现属性的自动注入有两步,首先把他注册进容器,sringboot只给容器内的组件提供给自动注入,第二步绑定配置文件,有以下两种实现方法
@ConfigurationProperties+@Componentapplication.properties:
pet.name="timcat" pet.age="18
@Component
//这样注入进去的组件就不能再用@Bean了
@ConfigurationProperties(prefix = "pet")
//从所有的配置中找pet前缀的注入进去
public class Pet {
String name;
String age;
}
这样我们再测试
Pet bean = run.getBean(Pet.class); System.out.println(bean.getAge()+bean.getName());
属性就自动注入了
报错记录:Spring Boot configuration annotation processor not found in classpath
@ConfigurationProperties+@EnableConfigurationPropertiesorg.springframework.boot spring-boot-configuration-processor
配置类
@Configuration
@EnableConfigurationProperties(User.class)
//这一步是将组件注册进容器
public class MyBeans {
}
注入的组件
@ConfigurationProperties(prefix = "user")
//绑定前缀
public class User {
String name;
String age;
Pet pet;
}
application.properties
user.age="21" user.name="hahaha"自动配置原理初探
我们可以看到主程序上有一个@SpringBootApplication的注解
点进去我们可以看到它是由3个注解合成的
@SpringBootConfiguration代表他是个配置类
@Component配置了他默认的扫描包路径
@EnableAutoConfiguration:
@AutoConfigurationPackage在指定目录下注册了一系列组件,就是主程序所在目录
@import(AutoConfigurationimportSelector.class)最终在meta-INF/spring.factories目录下加载所有需要装配的类,但是最终是否加载还取决于条件是否成立(@Conditional)



