模拟springboot自动转配原理
package com.tlj.app;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;
import java.util.List;
/**
* @Author: tlj
* @Date: 2022/9/20
* @Description:
*/
public class ApplicationTest {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
// 注册bean
context.registerBean("config",Config.class);
// 添加beanFactory后置处理器
context.registerBean(ConfigurationClassPostProcessor.class);
//启动容器
context.refresh();
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
}
@Configuration
@Import(MyImportSelector.class)
static class Config {
}
static class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// return new String[]{autoConfiguration1.class.getName()};
// 这么做的好处是将类的信息放到配置文件中 , 修改不需要修改代码,只需要修改配置文件
List<String> names = SpringFactoriesLoader.loadFactoryNames(MyImportSelector.class, null);
return names.toArray(new String[0]);
}
}
@Configuration
static class autoConfiguration1 {
@Bean
@ConditionalOnMissingBean
public com.tlj.app.parta.Bean bean1() {
return new com.tlj.app.parta.Bean();
}
}
}
reource 目录
spring.factories 文件
com.tlj.app.ApplicationTest$MyImportSelector=\
com.tlj.app.ApplicationTest.autoConfiguration1
由于使用了内部类的方式,所以将.替换成了$
编写jar配置类的时候,如果要让使用者可以复写配置类中的某个bean,可以使用 @ConditionalOnMissingBean 注解