springboot
自动配置原理
SpringBoot
的自动配置就是当spring
容器启动后,一些配置类、bean
对象就自动存入到了IOC
容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作
研究springboot
原理就是研究在springboot
项目中我们引入maven
依赖后,是如何将依赖jar
包中所定义的配置类,以及bean
加载到spring
的IOC
容器当中。
先在pom.xml
中引入对应的坐标,重新加载maven
,如下自定义了一个模块,通过maven
将其引入到当前模块中。
<dependency>
<groupId>com.example</groupId>
<artifactId>itheima-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
现在测试方法中判断是否能够获取在itheima-utils
模块中声明的bean
。利用applicationContext
的getBean
方法
@Autowired
private ApplicationContext applicationContext; //IOC容器对象
public void testBean(){
System.out.println(applicationContext.getBean(TokenParser.class));
}
报错不能找到
com.example
。解决方法:点开Maven
的itheima-utils
双击生命周期,双击install
,重新加载。
发现并不能获取到在itheima-utils
模块中TokenParser
类中通过@Component
注解声明的bean
对象。这是因为在当前测试类中的启动方法上的@SpringBootApplication
只能扫描到当前包及其子包。有如下两种方案解决:
方案一·:
@ComponentScan
组件扫描
@ComponentScan({"com.itheima","com.example"})
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
这种方法较为繁琐,因为每次获取到依赖jar
包中所定义的配置类,以及bean
,都需要配置扫描的包名
方法二:
@Import
导入。使用@Import
导入的类会被Spring
加载到IOC
容器中,导入形式主要有以下几种:
1.导入 普通类
@Import({TokenParser.class})
TokenParser
为JAR包的普通类
2.导入 配置类
@Import({HeaderConfig.class})
@Configuration
public class HeaderConfig {
@Bean
public HeaderParser headerParser(){
return new HeaderParser();
}
@Bean
public HeaderGenerator headerGenerator(){
return new HeaderGenerator();
}
}
如果要管理的bean对象来自于第三方(不是自定义的),是无法用 @Component 及衍生注解声明bean的,就需要用到 @Bean注解。
若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过 @Configuration 注解声明一个配置类。
通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。
如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配
3.导入 ImportSelector
接口实现类
@Import({MyImportSelector.class})
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.example.HeaderConfig"};
}
}
4.在第三方JAR包中实现@EnableHeaderConfig
注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)
public @interface EnableHeaderConfig {
}
使用时只需要让启动类上加上@EnableHeaderConfig
自定义starter
实际开发中,经常会定义一些公共组件,提供给各个项目团队使用。而在SpringBoot
的项目中,一般会将这些公共组件封装为SpringBoot
的 starter
步骤:
1.创建 aliyun-oss-spring-boot-starter
模块
starter不需要任何的JAVA代码只需要引入autoconfigure
的Maven依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
2.创建 aliyun-oss-spring-boot-autoconfigure
模块
先实现一个POJO
类定义,如本例的AliOSSProperties
,提供对应的GET,SETTER方法,并加上@ConfigurationProperties(prefix = "aliyun.oss")
,以便后续在yml文件中配置属性信息。
在实现一个工具类,完成静态方法的封装:
public class AliOSSUtils {
private AliOSSProperties aliOSSProperties;
public AliOSSProperties getAliOSSProperties() {
return aliOSSProperties;
}
public void setAliOSSProperties(AliOSSProperties aliOSSProperties) {
this.aliOSSProperties = aliOSSProperties;
}
/**
* 实现上传图片到OSS
*/
public String upload(MultipartFile file) throws IOException {
//获取阿里云OSS参数
String endpoint = aliOSSProperties.getEndpoint();
String accessKeyId = aliOSSProperties.getAccessKeyId();
String accessKeySecret = aliOSSProperties.getAccessKeySecret();
String bucketName = aliOSSProperties.getBucketName();
// 获取上传的文件的输入流
InputStream inputStream = file.getInputStream();
// 避免文件覆盖
String originalFilename = file.getOriginalFilename();
String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
//上传文件到 OSS
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
ossClient.putObject(bucketName, fileName, inputStream);
//文件访问路径
String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
// 关闭ossClient
ossClient.shutdown();
return url;// 把上传到oss的路径返回
}
}
在实现自动配置类
@Configuration
@EnableConfigurationProperties(AliOSSProperties.class)
public class AliOSSAutoConfiguration {
@Bean
public AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){ // 如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配
AliOSSUtils aliOSSUtils = new AliOSSUtils();
aliOSSUtils.setAliOSSProperties(aliOSSProperties);
return aliOSSUtils;
}
}
3.在 aliyun-oss-spring-boot-autoconfigure
模块中自定义自动配置功能,并定义resources
下的META-INF
下的spring
目录的org.springframework.boot.autoconfigure.AutoConfiguration.imports
在该文件下的全类名类会被Spring加载到IOC
容器中
com.aliyun.oss.AliOSSAutoConfiguration
这样在使用中只需要引入starter,在yml文件中配置所需要的信息即可