目录
1.配置优先级:
2.Bean的管理:
bean的作用域:
第三方bean:
方案一:
方案二:
SpringBoot原理:
扫描第三方包:
方案1:@ComponentScan 组件扫描
方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中)
1). 使用@Import导入普通类:
2). 使用@Import导入配置类:
3). 使用@Import导入ImportSelector接口实现类:
4). 使用第三方依赖提供的 @EnableXxxxx注解
自定义启动器starter:
1.自定义 aliyun-oos-spring-boot-starter 模块(起步依赖)
2.创建aliyun-oss-spring-boot-autoconfigure 自动配置模块
1.配置优先级:
在我们前面的课程当中,我们已经讲解了SpringBoot项目当中支持的三类配置文件:
-
application.properties
-
application.yml
-
application.yaml
配置文件优先级排名(从高到低):
-
properties配置文件
-
yml配置文件
-
yaml配置文件
五种配置方式的优先级: 命令行参数 > 系统属性参数 > properties参数 > yml参数 > yaml参数
2.Bean的管理:
bean的作用域:
在前面我们提到的IOC容器当中,默认bean对象是单例的 (只有一个实例对象)。在Spring中支持五种作用域,后三种在web环境才生效:
-
可以借助Spring中的@Scope注解来进行配置作用域
//默认bean的作用域为:singleton (单例)
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
//省略其他代码...
}
测试类:
@SpringBootTest
class SpringbootWebConfig2ApplicationTests {
@Autowired
private ApplicationContext applicationContext; //IOC容器对象
//bean的作用域
@Test
public void testScope(){
for (int i = 0; i < 10; i++) {
DeptController deptController = applicationContext.getBean(DeptController.class);
System.out.println(deptController);
}
}
}
ApplicationContext applicationContext; //为IOC容器对象 可以拿到IOC 容器中的bean对象
重启SpringBoot服务,运行测试方法,查看控制台打印的日志:
可以看到bean的作用域默认singleton 单例 容器中只会有一个bean对象
-
默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时) 在第一次使用时才会创建bean对象
第三方bean:
在我们项目开发当中,当这个类它不是我们自己编写的,而是我们引入的第三方依赖当中提供的,那么此时我们是无法使用 @Component
及其衍生注解来声明bean的,此时就需要使用@Bean
注解来声明bean 了。
因为第三方的类无法加@Component 被 spring项目扫描(默认只扫描启动类所在的包及其子包)
把第三方类对象放入 IOC容器:
方案一:
在启动类定义方法 返回的对象就会自动变为bean对象(切入到启动类不建议)
方案二:
1.在类上定义 @Configuration 注解
2.在方法上加入@Bean注解 返回的对象会自动变成bean对象
单独在conf包下定义配置类
-
通过
@Bean
注解的name 或 value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。 -
如果第三方bean需要依赖其他bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。
SpringBoot原理:
SpringBoot框架之所以使用起来更简单更快捷,是因为SpringBoot框架底层提供了两个非常重要的功能:一个是起步依赖,一个是自动配置。
起步依赖:
springboot-starter-web,这是web开发的起步依赖,在web开发的起步依赖当中,就集成了web开发中常见的依赖:json、web、webmvc、tomcat等。我们只需要引入这一个起步依赖,其他的依赖都会自动的通过Maven的依赖传递进来。
自动配置:
SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。
我们在我们整个项目中,也并未配置Gson这个类型的bean,为什么可以直接注入使用呢? 原因就是因为这个bean,springboot中已经帮我们自动配置完毕了,我们是可以直接使用的。
扫描第三方包:
如果 不在启动类所在的包及其子包的 包中的类也想被 IOC 容器 管理 @bean只针对一个对象
扫描别的包可以把别的包中@Component 类交给IOC管理
-
方案1:
@ComponentScan
组件扫描
@SpringBootApplication
@ComponentScan({"com.itheima","com.example"}) //指定要扫描的包
public class SpringbootWebConfigApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfigApplication.class, args);
}
}
在启动类加入@ComponentScan 注解可以自动扫描 别的包中的@Component注解加入IOC容器
我们进行项目开发时,当需要引入大量的第三方的依赖,就需要在启动类上配置N多要扫描的包,这种方式会很繁琐。而且这种大面积的扫描性能也比较低。
缺点:
-
使用繁琐
-
性能低
结论:SpringBoot中并没有采用以上这种方案。
方案2:@Import
导入(使用@Import
导入的类会被Spring加载到IOC容器中)
-
入形式主要有以下几种:
-
导入普通类
-
导入配置类
-
导入ImportSelector接口实现类
-
首先要把想要使用模块的 依赖 导入到spring项目模块中 才能找到对应的包
1). 使用@Import导入普通类:
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
@SpringBootApplication
public class SpringbootWebConfigApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfigApplication.class, args);
}
}
不用写@Component注解 类对象会被直接导入
2). 使用@Import导入配置类:
用配置类可以把多个bean对象一次放入IOC容器中
配置类:
启动类:
导入配置类IOC容器中会有 配置类对象 和 配置类中的两个bean对象
3). 使用@Import导入ImportSelector接口实现类:
ImportSelector接口实现类
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//返回值字符串数组(数组中封装了全限定名称的类)
return new String[]{"com.example.HeaderConfig"};
}
}
启动类
@Import(MyImportSelector.class) //导入ImportSelector接口实现类
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
以上三种方法 都i需要在启动类自己@Import 类 但是我们一般并不清楚 第三方类的名字
-
比较常见的方案就是第三方依赖给我们提供一个注解,这个注解一般都以@EnableXxxx开头的注解,注解中封装的就是@Import注解
4). 使用第三方依赖提供的 @EnableXxxxx注解
-
第三方依赖中提供的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)//指定要导入哪些bean对象或配置类
public @interface EnableHeaderConfig {
}
-
在使用时只需在启动类上加上@EnableXxxxx注解即可
@EnableHeaderConfig //使用第三方依赖提供的Enable开头的注解
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
自动配置原理源码入口就是 @SpringBootApplication
注解,在这个注解中封装了3个注解,分别是:
-
@SpringBootConfiguration
-
声明当前类是一个配置类
-
-
@ComponentScan
-
进行组件扫描(SpringBoot中默认扫描的是启动类所在的当前包及其子包)
-
-
@EnableAutoConfiguration
- 封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类) 在实现类重写的selectImports()方法,读取当前项目下所有依赖jar包中
META-
-
INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
两个文件里面定义的配置类(配置类中定义了@Bean注解标识的方法)。-
封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)
-
当SpringBoot程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息(类的全限定名)封装到String类型的数组中,最终通过@Import注解将这些配置类全部加载到Spring的IOC容器中,交给IOC容器管理。
在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件中定义的配置类非常多,而且每个配置类中又可以定义很多的bean,那这些bean都会注册到Spring的IOC容器中吗?
答案:并不是。 在声明bean对象时,上面有加一个以 @Conditional
开头的注解,这种注解的作用就是按照条件进行装配,只有满足条件之后,才会将bean注册到Spring的IOC容器中(下面会详细来讲解)
自定义启动器starter:
目的:将阿里云util 文件上传类对象 自动放到 IOC 容器中 可以直接注入使用
否则 在 不同项目中都需要重新写util类
只需要引入启动器依赖即可
springboot的启动器 默认会 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件中的配置类 并把配置类 中的 bean 对象加载到IOC容器中
我们只需要定义相同的路径 把我们 自己的配置类放到 .imports 文件中即可
·
1.自定义 aliyun-oos-spring-boot-starter 模块(起步依赖)
只需要有pom 文件即可
在pom 文件中 只需要引入 自动配置模块的依赖
2.创建aliyun-oss-spring-boot-autoconfigure 自动配置模块
EnableAutoConfigureAliyunOSS为util 的配置类
@Configuration // 声明为配置类:实现自动配置
public class EnableAutoConfigureAliyunOSS {
// 把阿里云的OSS文件上传对象交给spring容器管理。
// 阿里云对象需要配置信息对象的
// 阿里云的属性对象可以注入给文件上传对象。
@Bean
public OSSFileUpholdUtil ossFileUploadUtil() {
return new OSSFileUpholdUtil();
}
}
在 .import 文件中写入 配置类的路径 springboot自动配置时就会自动添加bean