@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; } }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。