1. 不需要注册到spring容器
万能的map
从配置文件加载k-v,比如配置完整的接口名称和实现类名称
private static final String DEFAULT_CONFIGURERS_PATH = "CodecConfigurer.properties";
private static final Map<Class<?>, Class<?>> defaultCodecConfigurers = new HashMap<>(4);
static {
try {
Properties props = PropertiesLoaderUtils.loadProperties(
new ClassPathResource(DEFAULT_CONFIGURERS_PATH, CodecConfigurerFactory.class));
for (String ifcName : props.stringPropertyNames()) {
String implName = props.getProperty(ifcName);
Class<?> ifc = ClassUtils.forName(ifcName, CodecConfigurerFactory.class.getClassLoader());
Class<?> impl = ClassUtils.forName(implName, CodecConfigurerFactory.class.getClassLoader());
defaultCodecConfigurers.put(ifc, impl);
}
}
catch (IOException | ClassNotFoundException ex) {
throw new IllegalStateException(ex);
}
}
public static <T extends CodecConfigurer> T create(Class<T> ifc) {
Class<?> impl = defaultCodecConfigurers.get(ifc);
if (impl == null) {
throw new IllegalStateException("No default codec configurer found for " + ifc);
}
return (T) BeanUtils.instantiateClass(impl);
}
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
T instance = (T) BeanUtils.instantiateClass(constructor, args);
2. spring容器
spring提供了类实例化,主要包括在xml文件中使用component-scan配置包路径,并使用@Service @Controller @Configuration @Bean等注解,以及spring-boot的@ConditionalOnBean、@ConditionalOnClass、@ConditionalOnProperty等按照条件配置注入的类。spring-boot使用约定大于配置的理念解放了spring繁琐的xml配置。
- @component
1. org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory执行doScan
2. org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents找到beandefinition之后生成beandefinitionholder并注册到spring容器
- @configuration
- 第三方jar包中的类注册到spring容器
spring-boot提供了更多的方式,
- @Import
Enable* 使用该注解引入配置类
ImportSelector接口 根据不同的入参判断返回bean名称列表
动态注册Bean(实现 ImportBeanDefinitionRegistrar 接口)
一般只要用户确切知道哪些Bean需要放入容器的话,自己可以通过spring 提供的注解来标识就可以了,比如@Component,@Service,@Repository,@Bean等。 如果是不确定的类,或者不是spring专用的,所以并不想用spring的注解进行侵入式标识,那么就可以通过@Import注解,实现ImportBeanDefinitionRegistrar接口来动态注册Bean
参考:
https://www.jianshu.com/p/7317626794fa