一,自动装配是什么
为什么我们在使用springboot时,只需要添加启动器坐标,容器中就会有启动器对应的bean,这都要得益于springboot的自动装配,springboot启动类会在程序运行时,读取META-INF/spring.factories
文件中需要自动装配的类,并根据不同类中的不同条件进行bean的装配。
二,自动装配的流程
@SpringBootApplication
public class ShopOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ShopOrderApplication.class, args);
}
}
在启动类中有一个名为@SpringBootApplication的注解,这个注解标注着这是要一个springboot应用,实现了自动装配@EnableAutoConfiguration,组件扫描@ComponentScan等功能,简化配置,提供默认行为加速了应用的开发和部署。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
//。。。
}
在这之中,@EnableAutoConfiguration便是自动装配的注解,以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置,@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;
再点进去进去看一下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
//。。。
}
这之中有自动配置包@AutoConfigurationPackage:
//AutoConfigurationPackage的子注解
//Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
还和我们需要关心的@Import,@Import中的导入了自动配置导入选择器AutoConfigurationImportSelector,在这个类中会向容器中导入组件:
导入所有需要自动配置的类后,根据类对应启动器中的自动配置类条件进行bean的装配,例如redis的自动配置类:
@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}