@Configuration注解简介说明
下文笔者讲述@Configuration注解的相关说明,如下所示
@Configuration注解简介
@Configuration是使用在类上的注解
表示一个对象是Bean定义的来源
@Configuration类通过@Bean注解方法声明Bean
@Configuration类的功能:
使用@Configuration注解的功能:
替代Spring中applicationContext.xml文件
使配置更加灵活和方便
当某个类标注@Configuration注解时
表示这个类是Spring一个配置类
能自动注册到IOC容器并进行实例化
例
@Configuration
class AppConfig {
@Bean
public Person person() {
return new Person() ;
}
}
AppConfig是一个配置类 在该类中通过@Bean标注方法注册Bean对象
@Component
static class AppConfig {
@Bean
public Person person() {
return new Person() ;
}
}
// 测试是否能够获取Person bean对象
try (GenericApplicationContext context = new GenericApplicationContext()) {
context.registerBean(AppConfig.class) ;
// ...
System.out.println(context.getBean(Person.class)) ;
}
使用@Configuration替换
@Configuration
static class AppConfig {
@Bean
public Person person() {
return new Person() ;
}
@Bean
public Date d1() {
System.out.println(person()) ;
return new Date() ;
}
@Bean
public Date d2() {
System.out.println(person()) ;
return new Date() ;
}
}
ConfigurationClassPostProcessor 实现原理
Spring提供了一个ConfigurationClassPostProcessor处理器 注册@Configuration注解。 该处理器是一个BeanFactoryPostProcessor
处理配置类
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// ...
// 处理配置类bean
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 获取所有的bean
String[] candidateNames = registry.getBeanDefinitionNames();
// 遍历
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName) ;
// 判断当前的bean是否有ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE属性
// 默认都是没有的,所以这里进入到else if 中
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
// 打印日志
}
// 在checkConfigurationClassCandidate会处理配置类的相应属性
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// ...
}
}
ConfigurationClassUtils
abstract class ConfigurationClassUtils {
public static final String CONFIGURATION_CLASS_FULL = "full";
public static final String CONFIGURATION_CLASS_LITE = "lite";
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
// 省去无关代码
// 获取到当前配置类的所有注解信息
AnnotationMetadata metadata = AnnotationMetadata.introspect(beanClass) ;
// 获取注解类@Configuration信息
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
// 如果@Configuration中的proxyBeanMethods属性为true,
那么就将当前配置类对应的BeanDefinition设置属性
// 标记为true,其实这里的目的就是要不要创建代理,如果为true创建代理
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
// 不创建代理
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
}
}
为配置类生成代理
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanFactory(ConfigurablelistableBeanFactory beanFactory) {
// ...
// 增强配置类,创建代理
enhanceConfigurationClasses(beanFactory);
}
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
// 获取设置的标记属性,要么是full,要么是lite
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
// 先保存到集合汇总
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// 确定配置类的class
Class<?> configClass = beanDef.getBeanClass();
// 创建代理
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
beanDef.setBeanClass(enhancedClass);
}
}
}
}
使用ConfigurationClassEnhancer#enhance 创建目标配置类的代理对象。
class ConfigurationClassEnhancer {
private static final Callback[] CALLBACKS = new Callback[] {
new BeanMethodInterceptor(),
new BeanFactoryAwareMethodInterceptor(),
NoOp.INSTANCE
}
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
return enhancedClass;
}
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(configSuperClass);
// 设置生成的子类要实现的接口,该接口实现了BeanFactoryAware,
// 所以容器在实例化初始化该代理对象的时候会自动注入当前容器的BeanFactory对象。
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// 这里有个作用就是为当前的代理bean添加BeanFactory类型的字段。
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
private Class<?> createClass(Enhancer enhancer) {
Class<?> subclass = enhancer.createClass();
Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
return subclass;
}
}
拦截配置方法
private static class BeanMethodInterceptor implements MethodInterceptor {
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
// 获取当前@Bean注解的方法名(也就是对应的BeanName)
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
// ...
// 从容器中查找对应的bean(也就是你调用的那个方法创建的bean对象)
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {
// 获取bean实例
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));
// ...
return beanInstance;
}
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


