用于标识一个类为配置类,与xml配置效果相似java
public class TestApplication { public static void main(String args[]) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); } } @Configuration public class AppConfig { @Bean public A a(){ return new A(); } @Bean public B b(){ return new B(); } } public class A { public A(){ System.out.println("Call A constructor"); } } public class B { public B(){ System.out.println("Call B constructor"); } }
上面的例子应该是@Configuration最广泛一种使用场景了,在@Configuration class下面配置@Bean method,用于想Spring Ioc容器注入bean.但其实咱们把AppConfig的@Configuration注解去掉,对应的Bean也是能够被注入到容器中去的。ios
咱们给AppConfig改写一下,以下:app
@Configuration @EnableAspectJAutoProxy public class AppConfig { @Bean public A a(){ b(); return new A(); } @Bean public B b(){ return new B(); }
再去执行TestApplication#main,那么执行结果会是什么样呢?jvm
Call A constructor Call B constructor
嗯哼?按照Java的语法,B的构造函数应该是被调用了两次啊?为何只有输出一句Call B constructor
?ide
这其实就是@Configuration再发挥做用啦,不信你去掉@Configuration,再去运行一下,就会发现B的构造函数被执行了两次。函数
官方给出了这样一段解释对于被@Configuration注解的类post
In common scenarios,
@Beanmethods are to be declared within
@Configurationclasses, ensuring that “full” mode is always used and that cross-method references therefore get redirected to the container’s lifecycle management.
this
在通常状况下,@Bean method 是被声明在@Configuration类中的,以确保 full mode老是被使用,而且跨方法的引用会被重定向到容器生命周期管理。
代理
原来Spring将被@Configuration注解的配置类定义为full configuration, 而将没有被@Configuration注解的配置类定义为lite configuration。full configuration能重定向从跨方法的引用,从而保证上述代码中的b bean是一个单例.rest
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { /** * 调用无参构造函数,实例化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner * 同时会调用父类GenericApplicationContext无参构造函数实例化一个关键的工厂DefaultListableBeanFactory * 同时还会注册一些开天辟地的后置处理器到beanDefinitionMap,这些后置处理器有bean工厂后置处理器;有bean后置处理器 */ this(); //将componentClasses注册到beanDefinitionMap集合中去 register(componentClasses); refresh(); }
跟踪refresh()
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. //供上下文(Context)子类继承,容许在这里后置处理bean factory postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. //按顺序调用BeanFactoryPostProcessor,这里的按顺序仅实现了PriorityOrdered和Ordered的语意,未实现@Order注解的语意 //经过调用ConfigurationConfigPostProcessor#postProcessBeanDefinitionRegistry //解析@Configuration配置类,将自定义的BeanFactoryPostProcessor、BeanPostProcessor注册到beanDefinitionMap //接着实例化全部(包括开天辟地)的BeanFactoryPostProcessor,而后再调用BeanFactoryPostProcessor#postProcessBeanFactory invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. //按顺序将BeanPostProcessor实例化成bean并注册到beanFactory的beanPostProcessors, //这里的按顺序仅实现了PriorityOrdered和Ordered的语意,未实现@Order注解的语意 //由于BeanPostProcessor要在普通bean初始化()先后被调用,因此须要提早完成实例化并注册到beanFactory的beanPostProcessors registerBeanPostProcessors(beanFactory); // Initialize message source for this context. //注册国际化相关的Bean initMessageSource(); // Initialize event multicaster for this context. //为上下文注册应用事件广播器(用于ApplicationEvent的广播),若是有自定义则使用自定义的,若是没有则内部实例化一个 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. //注册全部(静态、动态)的listener,并广播earlyApplicationEvents registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //实例化用户自定义的普通单例Bean(非开天辟地的、非后置处理器) finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
跟踪invokeBeanFactoryPostProcessors(beanFactory)
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
跟踪invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); //此处调用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry, //解析配置类,为配置中的bean定义生成对应beanDefinition,并注入到registry的beanDefinitionMap invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. //调用ConfigurationClassPostProcessor#postProcessBeanFactory加强配置类(经过cglib生成加强类,load到jvm内存, //设置beanDefinition的beanClass为加强类) //为何要加强配置类?主要是为了让@Bean生成的bean是单例, invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
跟踪invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
private static void invokeBeanFactoryPostProcessors( Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) { for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } }
跟踪ConfigurationClassPostProcessor#postProcessBeanFactory
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { int factoryId = System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { // BeanDefinitionRegistryPostProcessor hook apparently not supported... // Simply call processConfigurationClasses lazily at this point then. processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); } //为@Configuration注解的类生成加强类(若是有必要),并替换bd中的beanClass属性, enhanceConfigurationClasses(beanFactory); beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); }
到了这一步谜底几乎已经揭晓了,@Configuration class是经过加强来实现它的语义的。经过加强把跨方法的引用调用重定向到Spring生命周期管理.咱们近一步探索下这个enhanceConfigurationClasses方法
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>(); for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE); MethodMetadata methodMetadata = null; if (beanDef instanceof AnnotatedBeanDefinition) { methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata(); } if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) { // Configuration class (full or lite) or a configuration-derived @Bean method // -> resolve bean class at this point... AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef; if (!abd.hasBeanClass()) { try { abd.resolveBeanClass(this.beanClassLoader); } catch (Throwable ex) { throw new IllegalStateException( "Cannot load configuration class: " + beanDef.getBeanClassName(), ex); } } } //在ConfigurationClassUtils.checkConfigurationClassCandidate方法中会标记Configuration is full or lite if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) { if (!(beanDef instanceof AbstractBeanDefinition)) { throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass"); } else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) { logger.info("Cannot enhance @Configuration bean definition '" + beanName + "' since its singleton instance has been created too early. The typical cause " + "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + "return type: Consider declaring such methods as 'static'."); } configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } if (configBeanDefs.isEmpty()) { // nothing to enhance -> return immediately return; } ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer(); for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) { AbstractBeanDefinition beanDef = entry.getValue(); // If a @Configuration class gets proxied, always proxy the target class beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); // Set enhanced subclass of the user-specified bean class Class<?> configClass = beanDef.getBeanClass(); //为@Configuration注解的类生成加强类 Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader); if (configClass != enhancedClass) { if (logger.isTraceEnabled()) { logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " + "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName())); } beanDef.setBeanClass(enhancedClass); } } }
看到有那么一句话Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
很明显了,使用cglib技术为config class生成一个enhancedClass,再经过beanDef.setBeanClass(enhancedClass);
修改beanDefinition的BeanClass属性,在bean实例化阶段,会利用反射技术将beanClass属性对应的类实例化出来,因此最终实例化出来的@Configuration bean是一个代理类的实例。这里稍微提一下为何要使用cglib
,而不是jdk动态代理
,主要是由于jdk动态代理
是基于接口的,而这里AppConfig并无实现任何接口,因此必须用cglib
技术。
被@Configuration 注解的类,是 full configuration class,该类会被加强(经过cglib
),从而实现跨方法引用调用被重定向到Spring 生命周期管理,最终保证@Bean method生成的bean是一个单例。