springboot自动装配重要注解
- @EnableAutoConfiguration @Import
作用:将发现的类交给spring管理,先看一下@import注解在哪里用到
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) // springboot启动类中@EnableAutoConfiguration注解中
public @interface EnableAutoConfiguration { // springboot启动类@SpringBootApplication注解中
这里我们开始试验一下import注解的作用
先创建一个demot类
//@Import(User.class) // 先注释这个注解运行下面的结果
@Configuration // 声名配置类的注解
public class ImportTestDemo {
public static void main(String[] args) {
// 这个我们可以理解为spring通过注解方式发现并注册bean工厂的对象
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ImportTestDemo.class);
// 所有对象名字集合
String[] names = ac.getBeanDefinitionNames();
for (String name : names) {
// 打印看下bean工厂里面有那些对象
System.out.println(name);
System.out.println("----------------");
}
}
}
看下运行结果,只有我们声名的配置类打应出来了
importTestDemo
----------------
接下来我们用上import注解,并运行一下
@Import(User.class) // User是我自定义的一个实体
@Configuration // 声名配置类的注解
public class ImportTestDemo {
public static void main(String[] args) {
// 这个我们可以理解为spring通过注解方式发现并注册bean工厂的对象
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ImportTestDemo.class);
// 所有对象名字集合
String[] names = ac.getBeanDefinitionNames();
for (String name : names) {
// 打印看下bean工厂里面有那些对象
System.out.println(name);
System.out.println("----------------");
}
}
}
这个时候我们发现User对象也从spring容器中打印出来了,证明Impot注解有效果
importTestDemo
----------------
com.example.springbootredisson.bean.User
----------------
了解一下AutoConfigurationImportSelector的类,在第一个源码图中@Import中注解属性能看到
我们自己来实现一下ImportSelect
public class ImportSelectDemo implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 这里写死试试效果,当然spring有更优雅的代码检测出项目中的类
return new String[]{Goods.class.getName(), User.class.getName()};
}
}
@Configuration
@Import(ImportSelectDemo.class) // 自己实现的ImportSelect类
public class ImportTestDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ImportTestDemo.class);
String[] names = ac.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
System.out.println("----------------");
}
}
}
importTestDemo
----------------
com.example.springbootredisson.bean.Goods
----------------
com.example.springbootredisson.bean.User
----------------
到这里看到@Import和就是发现并注册类到spring容器中的作用
@EnableAutoConfiguration 注解作用就是将发现的类注册到ioc容器中,通过实现AutoConfigurationImportSelector这个类来发现并注册。下面再看来看importSelect这个类
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
// 通过配置文件spring.factories发现类
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
// 这里的返回值就是类对象的路径
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
在往下看看getAutoConfigurationEntry(annotationMetadata)这个方法
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 获取spring.factories中的类路径 这里是springboot自动装配的主要方法
List<String> configurations = getCandidateConfigurations(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);
}
打开mybaties的starter看看是否有spring.factory配置文件
Snipaste_2021-02-24_23-18-18.png
结论:springboot读取spring.factories配置文件,读取配置文件加载类到ioc中,这就是第三方starter的原理,也就是springboot自动装配的原理。
因此我们在springboot中只需要引入第三方starter 就能开箱即用,同理我们可以自己打包一个starter给另外一个项目
使用如何自己写一个starter,这个很简单,em...百度一下就好了
网友评论