一. 什么是自动装配
在没有springboot之前,我们使用spring如果需要引用第三方包的功能,则需要使用xml或者java进行显示配置,比如web.xml,mybatis-config.xml
现在有了springboot自动装配功能后,我们只需要引入对于的pom,开启注解就可以了,比如
@EnableFeign , @EnableSwagger2
另外,在spring工程中引入普通jar包,是无法将jar包内的bean扫描进beanFactory, 除非指定classpath(import jar包中的resources)
二 如何实现自动装配
核心注解SpringBootApplication
@SpringBootConfiguration //底层就是@Configuration
@EnableAutoConfiguration // 开启自动配置,注册AutoConfigurationPackages,加载META-INFO/spring.factories中的类
@ComponentScan(excludeFilters = { // TODO 这两个排除过滤器TypeExcludeFilter和AutoConfigurationExcludeFilter暂不知道啥作用
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
主要核心就是
- @EnableAutoConfiguration , 启用 SpringBoot 的自动配置机制
- @ComponentScan , 扫描被
@Component注解的 bean,注解默认会扫描启动类所在的包下所有的类
1.1 @EnableAutoConfiguration
核心注解有:
- @AutoConfigurationPackage , 内部 import了 AutoConfigurationPackages.Registrar.class ,就是注册AutoConfigurationPackages这个类,即默认包所在位置
- @Import(AutoConfigurationImportSelector.class) 内部process方法扫描spring.factories中的有效bean
1.2 @ComponentScan
spring自带的注解,扫描包下的bean,远古时期使用xml就使用过这个功能
思维导图
www.processon.com/embed/6275b…
三 如何自己实现一个starter
1. starter工程
1.1 主服务对象Service
这里做个简单演示类, 这个对象时starter中的主要服务提供者
public class ProviderService {
public ProviderService(String name) {
this.name = name;
}
private String name;
public void mainService() {
System.out.println("Hello World!" + this.name);
}
}
1.2 自动配置类
这个是自动配置类,用于嵌入引用者的springboot中去
/**
* @description: 配置类,一般是这个jar包的所有配置和使用对象
* @author: 沈琪
**/
@Configuration
@EnableConfigurationProperties
@ConditionalOnBean(value = ProviderRemark.class)
public class ProviderConfiguration {
//属性注入,配置到被引用的项目中
@Value("${my.name}")
private String name;
//暴露出服务的提供类,让其可以被外部工程注入
@Bean
ProviderService getInstance() {
return new ProviderService(name);
}
}
1.3 Enable注解及开关类
适用于外部工程,用于显示启用该starter,
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ProviderRemark.class}) //引入开关,打开自动装配
public @interface EnableProvider {
}
public class ProviderRemark {
}
2. 外部工程
//显示开启这个starter
@EnableProvider
@SpringBootApplication
public class TestApplication implements ApplicationContextAware, CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
private static ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ctx = applicationContext;
}
@Override
public void run(String... args) throws Exception {
//这里就可以使用到starter中的方法了
ProviderConfiguration providerConfiguration = ctx.getBean(ProviderConfiguration.class);
System.out.println(providerConfiguration == null);
ProviderService providerService = ctx.getBean(ProviderService.class);
providerService.mainService();
}
}