今天我们分析springboot自动装配,也是一个常见面试题,今天我们分析一下
什么是自动装配
比如我们的项目中,要使用redis,我们仅仅需要进入redis-start依赖包,然后使用@Autowired,就可以使用我们的redis的api接口,这个结果就是springboot自动装配的成果
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
代码语言:javascript复制@Autowired
private RedissonClient redissionClient;
熟悉spring的人知道,我们直接这样使用,是因为我们的redissonClient是放入了IOC容器中了,所以我们这里直接从IOC拿到就直接使用
第三方的Bean实例放到IOC有哪些方式呢
使用xml
代码语言:javascript复制<bean id="redissionClient" class="org.redisson.api.RedissonClient">
代码语言:javascript复制public class XmlBeanTest {
public static void main(String[] args){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
RedissonClient redissionClient = (RedissonClient) applicationContext.getBean("redissionClient");
}
}
使用注解
代码语言:javascript复制@Configuration
@ComponentScan(basePackages = {"com.my.test"})
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
return new RedissonClient();
}
}
代码语言:javascript复制public class AnnotationBeanTest {
public static void main(String[] args){
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(RedisConfig.class);
System.out.println(ctx.getBean("redissonClient"));
}
}
上面的一意思就是我们使用@ComponentScan稻苗com.my.test.下的包,然后使用@Configuration把Bean实例(RedissonClient)注入到IOC容器中,
我们还要讲一个重点就是@Import,他的意思就是把多个配置文件合并成一个配置文件如
代码语言:javascript复制@Configuration
@ComponentScan(basePackages = {"com.other.test"})
public class OtherConfig {
@Bean
public OtherClient otherClient() {
return new OtherClient();
}
}
代码语言:javascript复制@Configuration
@Import(OtherConfig.class)
@ComponentScan(basePackages = {"com.my.test"})
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
return new RedissonClient();
}
}
代码语言:javascript复制public class AnnotationBeanTest {
public static void main(String[] args){
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(RedisConfig.class);
System.out.println(ctx.getBean("otherClient"));
}
}
使用import我们就可以拿到其他配置文件的实例Bean(otherClient),现在我们知道使用xml和注解的方式可以把bean实例放入到IOC容器中
此时,我们再看看一开始第三方包如何进行自动装配,下图就是我们的第三方包基本目录,举个例子如图
其中spring.factories的内容如下图
代码语言:javascript复制org.springframework.boot.autoconfigure.EnableAutoConfiguration
=org.redisson.spring.cache.RedissonCacheStatisticsAutoConfiguration
config目录下的配置文件如下内容
代码语言:javascript复制@Configuration
@AutoConfigureAfter({CacheAutoConfiguration.class})
@ConditionalOnBean({CacheManager.class})
@ConditionalOnClass({CacheMeterBinderProvider.class, RedissonCache.class})
public class RedissonCacheStatisticsAutoConfiguration {
public RedissonCacheStatisticsAutoConfiguration() {
}
@Bean
public RedissonCacheMeterBinderProvider redissonCacheMeterBinderProvider() {
return new RedissonCacheMeterBinderProvider();
}
}
首先配置文件和我们上面说的一样使用@Configuration和@Bean注解,此时我们要解决两个问题
- 我们要知道配置类在哪个目录下 spring使用的技术就是SPI原理,约定配置类都写在META-INF/spring.factories,使用SpringFactoriesLoade加载路径下的文件
- 如何加载这个动态配置类
实现ImportSelector接口,然后再selectImport里面实现加载配置类,返回给sprign对应的配置类列表如xxxAutoConfiguration
代码语言:javascript复制public interface ImportSelector {
String[] selectImports(AnnotationMetadata var1);
}
以上就是springboot的自动装配的基本实现原理,我们虽然没有看源码,但是基本的思路就是文中所讲