8、配置类的加载

    第二小节spring已经准备好了配置类,就差读取了。现在我们就顺着spring的流程继续往下分析。

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
        //用于判断当前配置类是否需要被跳过,在spring筛选配置类的时候已经
        //使用条件进行筛选过一次,但是除了@ComponentScan之外跳过的都是ConfigurationPhase.PARSE_CONFIGURATION阶段的
        //所以还是需要进行ConfigurationPhase.REGISTER_BEAN阶段的筛选
        //除此之外,如果一个类的被其他类引入,而其他类都是被跳过的,那么这个
        //引入类也会被跳过,即使它并没有设置@Conditional注解
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
		    //从ConfigurationClass中加载BeanDefinition
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
		}
	}

    在真正解析前还是要进行一些准备工作的,比如剔除在注册阶段被跳过的配置类

private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,
			TrackedConditionEvaluator trackedConditionEvaluator) {
        //跳过ConfigurationPhase.REGISTER_BEAN阶段的配置类
		if (trackedConditionEvaluator.shouldSkip(configClass)) {
			String beanName = configClass.getBeanName();
			//判断是否已经注册了这个被跳过的类,如果已经注册,那么需要移除
			if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
				this.registry.removeBeanDefinition(beanName);
			}
			//如果这个类存在被引入集合中,那么也需要剔除
			this.importRegistry.removeImportingClassFor(configClass.getMetadata().getClassName());
			return;
		}
        //如果当前类是被引入的,那么进行注册,这里的注册过程和注册被
        //@Component注解的class是一样的,此处不过多赘述
        //但是为什么只注解被引入的呢?因为不是被引入的类已经注册过了,我
        //们解析配置类的时候都是从已经注册的BeanDefinition中进行筛选的
        //只有引入的类没有被注册
        //(1)
		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}
		//获取配置类中被@Bean注解的方法
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		    //通过@Bean方法加载BeanDefinition
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}
		//通过引入的xml配置文件获取BeanDefinition
		//这里和我们前面分析解析配置文件是一样的,如果没有提供BeanDefinitionReader就判断是否以.groovy结尾的,如果是创建GroovyBeanDefinitionReader
		//否则使用XmlBeanDefinitionReader,groovy是一个兼容java语法的特定领域类动态语言
		//感兴趣的,可以去学习一下
		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		//通过引入的ImportBeanDefinitionRegistrar注册BeanDefinition
		//直接调用registerBeanDefinitions方法
		loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
	}
	
	
	//(1)从被引入的配置类进行解析,然后注册,这段代码很眼熟,因为我们
	//在解析被@Component注解的类的时候就分析过这段代码,这里不过多赘述
	private void org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
	   //获取注解元数据
		AnnotationMetadata metadata = configClass.getMetadata();
		AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
        //从@Scope中读取生命周期,scope代理模式
		ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
		configBeanDef.setScope(scopeMetadata.getScopeName());
		//获取beanName生成器
		String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
		//解析通用注解属性,如@Lazy,@DependsOn,@DependsOn
		AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
		//如果设置了scope代理模式,那么会对当前BeanDefinition进行装饰,
		//使用ScopedProxyFactoryBean的BeanDefinition装饰原始的BeanDefinition
		//这个ScopedProxyFactoryBean实现了BeanFactoryAware接口,代理的方///法在setBeanFactory方法中实现
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		//注册BeanDefinition
		this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
		configClass.setBeanName(configBeanName);

		if (logger.isDebugEnabled()) {
			logger.debug("Registered bean definition for imported class '" + configBeanName + "'");
		}
	}
	

    上面那段代码主要进行了被引入类的注册,@Bean方法注册,引入配置资源的注册,ImportBeanDefinitionRegistrar的调用注册,除了@Bean方法,其他注册方式都已经在配置文件加载和@Component注解的时候已经分析过了,而ImportBeanDefinitionRegistrar的调用又比较简单,只是简单的调用registerBeanDefinitions方法进行注册,所以这几种注册方式,不再多少,我主要研究怎么从@Bean方法中加载BeanDefinition。

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
        //获取这个bean方法对应的配置类
		ConfigurationClass configClass = beanMethod.getConfigurationClass();
		//获取方法元数据,并且继承了AnnotatedTypeMetadata接口
		//所以这个实例具有获取注解,方法名,注解属性等能力
		MethodMetadata metadata = beanMethod.getMetadata();
		//获取方法名
		String methodName = metadata.getMethodName();

		// Do we need to mark the bean as skipped by its condition?
		//根据方法上的@Conditional注解,判断是否在ConfigurationPhase.REGISTER_BEAN阶段跳过
		if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
		    //记录被跳过的方法名
			configClass.skippedBeanMethods.add(methodName);
			return;
		}
		//这里似乎在告诉我们只要有一个相同名字的方法被跳过了,那么
		//这个类的所有重载方法都会被跳过???
		if (configClass.skippedBeanMethods.contains(methodName)) {
			return;
		}

		// Consider name and any aliases
		//获取beanName和别名
		AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
		List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name")));
		String beanName = (names.size() > 0 ? names.remove(0) : methodName);

		// Register aliases even when overridden
		//注册别名,不是简单进行注册,会进行别名已存在检查和别名循环检查
		for (String alias : names) {
			this.registry.registerAlias(beanName, alias);
		}

		// Has this effectively been overridden before (e.g. via XML)?
		// (1)
		if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
			return;
		}
        //configClass,配置类,metadata,对应的方法元数据
		ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
		//和创建其他的BeanDefinition一样的套路,记录资源
		beanDef.setResource(configClass.getResource());
		beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
        //如果是静态方法,那么以静态工厂bean处理
		if (metadata.isStatic()) {
			// static @Bean method
			beanDef.setBeanClassName(configClass.getMetadata().getClassName());
			beanDef.setFactoryMethodName(methodName);
		}
		else {
			// instance @Bean method
			//如果不是静态方法,设置工厂bean,这里对应我们在xml配置文件
			//中设置的factory-bean
			beanDef.setFactoryBeanName(configClass.getBeanName());
			//设置工厂方法名,并标识当前方法唯一
			beanDef.setUniqueFactoryMethodName(methodName);
		}
		//设置其装配类型为构造器自动装配
		beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
		//设置跳过@Required为true检查
		beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
        
        //处理通用注解@Lazy,@Primary,@DependsOn等注解
		AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
        //获取autowire属性值
		Autowire autowire = bean.getEnum("autowire");
		//如果是Autowire.BY_NAME 或者 Autowire.BY_TYPE,才会设置这个值,
		//否则用默认值
		if (autowire.isAutowire()) {
			beanDef.setAutowireMode(autowire.value());
		}
        //获取初始化方法名
		String initMethodName = bean.getString("initMethod");
		if (StringUtils.hasText(initMethodName)) {
			beanDef.setInitMethodName(initMethodName);
		}
        //获取销毁方法
		String destroyMethodName = bean.getString("destroyMethod");
		if (destroyMethodName != null) {
			beanDef.setDestroyMethodName(destroyMethodName);
		}

		// Consider scoping
		//获取@Scope注解值
		ScopedProxyMode proxyMode = ScopedProxyMode.NO;
		AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
		if (attributes != null) {
			beanDef.setScope(attributes.getAliasedString("value", Scope.class, configClass.getResource()));
			proxyMode = attributes.getEnum("proxyMode");
			if (proxyMode == ScopedProxyMode.DEFAULT) {
				proxyMode = ScopedProxyMode.NO;
			}
		}

		// Replace the original bean definition with the target one, if necessary
		BeanDefinition beanDefToRegister = beanDef;
		//如果设置了Scope代理模式,那么原始的BeanDefinition会被装饰
		if (proxyMode != ScopedProxyMode.NO) {
			BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
					new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
			beanDefToRegister = new ConfigurationClassBeanDefinition(
					(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
		}

		if (logger.isDebugEnabled()) {
			logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",
					configClass.getMetadata().getClassName(), beanName));
		}
        //注册bean定义
		this.registry.registerBeanDefinition(beanName, beanDefToRegister);
	}
	
	//(1)
	protected boolean isOverriddenByExistingDefinition(BeanMethod beanMethod, String beanName) {
	    //如果不存在,直接返回false
		if (!this.registry.containsBeanDefinition(beanName)) {
			return false;
		}
		BeanDefinition existingBeanDef = this.registry.getBeanDefinition(beanName);

		// 如果已经存在的BeanDefinition也是通过配置类加载进来的
		//并且来自同一个配置类,那么保留原有BeanDefinition
		//那如果不同方法定义的@Bean注解指定的beanName相同,也会被跳过???
		//当然按照逻辑来讲,如果出现这种情况,说明这个配置类已经被加载过了,被跳过也很正常
		if (existingBeanDef instanceof ConfigurationClassBeanDefinition) {
			ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef;
			return (ccbd.getMetadata().getClassName().equals(beanMethod.getConfigurationClass().getMetadata().getClassName()));
		}

		// A bean definition resulting from a component scan can be silently overridden
		// by an @Bean method, as of 4.2...
		//如果是扫描出来的BeanDefinition,那么允许@Bean注释的覆盖扫描的
		if (existingBeanDef instanceof ScannedGenericBeanDefinition) {
			return false;
		}

		// Has the existing bean definition bean marked as a framework-generated bean?
		// -> allow the current bean method to override it, since it is application-level
		//如果BeanDefinition角色不是用户定义的,那么允许进行覆盖
		if (existingBeanDef.getRole() > BeanDefinition.ROLE_APPLICATION) {
			return false;
		}

		// At this point, it's a top-level override (probably XML), just having been parsed
		// before configuration class processing kicks in...
		//如果存在的BeanDefinition是由配置文件解析进来的,那么需要判断是否
		//允许覆盖已有的BeanDefinition,不允许会抛出错误,允许的话也不会进行覆盖
		if (this.registry instanceof DefaultListableBeanFactory &&
				!((DefaultListableBeanFactory) this.registry).isAllowBeanDefinitionOverriding()) {
			throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
					beanName, "@Bean definition illegally overridden by existing bean definition: " + existingBeanDef);
		}
		if (logger.isInfoEnabled()) {
			logger.info(String.format("Skipping bean definition for %s: a definition for bean '%s' " +
					"already exists. This top-level bean definition is considered as an override.",
					beanMethod, beanName));
		}
		return true;
	}
	

    到此,注解解析配置类注册BeanDefinition的方式就结束了,剩下的是一些收尾工作。由于ConfigurationClassPostProcessor也是实现了BeanFactoryPostProcessor接口的,所以最后也会调用postProcessBeanFactory方法,spring在这里进行了一些增强处理,为什么要进行增强呢?那是因为@Bean标注的方法需要进行特殊处理,具体我们继续看代码。

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<String, AbstractBeanDefinition>();
		//筛选出被@Configuration注解的BeanDefinition
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
			    //如果不是AbstractBeanDefinition,那么不能被增强,因为
			    //spring增强需要使用到属性的获取和设置能力
				if (!(beanDef instanceof AbstractBeanDefinition)) {
					throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
							beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
				}
				//如果这个对象已经存在了单例bean集合中,发出警告
				else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
					logger.warn("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'.");
				}
				//保存待增强的BeanDefinition
				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
			//设置为cglib代理
			beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
			try {
				// Set enhanced subclass of the user-specified bean class
				//解析配置类
				Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
				//生成被增强的类
				//(1)
				Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
				//如果当前配置类被cglib代理增强,那么替换掉原来的配置类
				//将BeanDefinition设置成cglib代理后的类
				if (configClass != enhancedClass) {
					if (logger.isDebugEnabled()) {
						logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
								"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
					}
					beanDef.setBeanClass(enhancedClass);
				}
			}
			catch (Throwable ex) {
				throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
			}
		}
	}
	
	
	//(1)
	public Class<?> enhance(Class<?> configClass, ClassLoader classLoader) {
	    //如果这个配置已经实现了EnhancedConfiguration接口,EnhancedConfiguration接口又继承了BeanFactoryAware接口
	    //那么无需再创建,直接返回
		if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
			if (logger.isDebugEnabled()) {
				logger.debug(String.format("Ignoring request to enhance %s as it has " +
						"already been enhanced. This usually indicates that more than one " +
						"ConfigurationClassPostProcessor has been registered (e.g. via " +
						"<context:annotation-config>). This is harmless, but you may " +
						"want check your configuration and remove one CCPP if possible",
						configClass.getName()));
			}
			return configClass;
		}
		//创建被增强的类
		//(2)(3)
		Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
		if (logger.isDebugEnabled()) {
			logger.debug(String.format("Successfully enhanced %s; enhanced class name is: %s",
					configClass.getName(), enhancedClass.getName()));
		}
		return enhancedClass;
	}
	
	//(2)
	private Enhancer newEnhancer(Class<?> superclass, ClassLoader classLoader) {
	    //创建增强器
		Enhancer enhancer = new Enhancer();
		//设置超类为当前配置类
		enhancer.setSuperclass(superclass);
		//设置接口为EnhancedConfiguration,这是一个标记接口,它继承了BeanFactoryAware接口
		enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
		//是否使用代理工厂(org.springframework.cglib.proxy.Factory)
		enhancer.setUseFactory(false);
		//设置命名策略,也就是给生成的代理类生成名字
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		//设置生成策略,BeanFactoryAwareGeneratorStrategy生成策略会给
		//新生成的类增加一个BeanFactory属性字段
		enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
		//设置回调过滤函数
		enhancer.setCallbackFilter(CALLBACK_FILTER);
		//设置回调对象的类型
		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
		return enhancer;
	}
	
    //(3)
    private Class<?> createClass(Enhancer enhancer) {
        //创建增强类,也就是配置类的子类
		Class<?> subclass = enhancer.createClass();
		// Registering callbacks statically (as opposed to thread-local)
		// is critical for usage in an OSGi environment (SPR-5932)...
	    //将回调设置到生成子类的CGLIB$SET_STATIC_CALLBACKS静态字段中
		Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
		return subclass;
	}
	

    这里我们使用到两个回调实现,BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor

//BeanMethodInterceptor

public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
					MethodProxy cglibMethodProxy) throws Throwable {
            
            //获取代理类对象的BeanFactory对象
			ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
			//通过@Bean获取对应beanName
			String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

			// Determine whether this bean is a scoped-proxy
			//从这个方法@Scope中判断是否需要scope代理
			Scope scope = AnnotationUtils.findAnnotation(beanMethod, Scope.class);
			if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
			    //获取scope代理beanName  格式为 scopedTarget. + beanName
				String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
				//判断当前类是否正在创建,如果正在创建将scopedBeanName
				//赋值给beanName
				if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
					beanName = scopedBeanName;
				}
			}

		    //判断BeanFactory中是否包含指定工厂bean,并且是否包含其非&前缀的bean
			if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
					factoryContainsBean(beanFactory, beanName)) {
				//获取工厂bean
				Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
				//如果当前工厂bean是scope代理工厂,那么不做进一步的代理
				if (factoryBean instanceof ScopedProxyFactoryBean) {
					// Pass through - scoped proxy factory beans are a special case and should not
					// be further proxied
				}
				else {
					// It is a candidate FactoryBean - go ahead with enhancement
					return enhanceFactoryBean(factoryBean, beanFactory, beanName);
				}
			}
            //判断当前正在调用的方法和beanMethod是否一样,这里的一样
            //是指方法名一样,参数类型一样
            //内部进行实例化策略的ThreadLocal字段进行对比,如果一样
            //那么说明此时是在实例化bean的阶段
			if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
				// The factory is calling the bean method in order to instantiate and register the bean
				// (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
				// create the bean instance.
				//如果当前实例时调用的工厂方法返回值是BeanFactoryPostProcessor类型的,那么发出警告
				//因为在实例bean阶段通过工厂方法制造的BeanFactoryPostProcessor
				//是没法进行BeanFactory进行后置处理,也无法处理@Autowired,@PostConstruct,@Resource,@Configuration
				//可使用静态static修饰方法,因为我们在调用BeanFactory后置
				//处理器的时候,为了避免因早期实例化对象而导致未经过后置
				//处理器处理,spring禁止了早期实例化,所以像这种在实例化
				//bean阶段创建的BeanFactoryPostProcessor是不会被特殊处理的
				if (logger.isWarnEnabled() &&
						BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
					logger.warn(String.format("@Bean method %s.%s is non-static and returns an object " +
							"assignable to Spring's BeanFactoryPostProcessor interface. This will " +
							"result in a failure to process annotations such as @Autowired, " +
							"@Resource and @PostConstruct within the method's declaring " +
							"@Configuration class. Add the 'static' modifier to this method to avoid " +
							"these container lifecycle issues; see @Bean javadoc for complete details.",
							beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
				}
				//调用父类方法进行bean的创建
				return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
			}
			else {
			    //如果不是工厂方法的调用,那么说明是@Bean方法的调用
				// The user (i.e. not the factory) is requesting this bean through a
				// call to the bean method, direct or indirect. The bean may have already been
				// marked as 'in creation' in certain autowiring scenarios; if so, temporarily
				// set the in-creation status to false in order to avoid an exception.
				
				boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
				try {
				    //如果当前bean正在创建当中,那么将正在创建的状态修改为false
					if (alreadyInCreation) {
						beanFactory.setCurrentlyInCreation(beanName, false);
					}
					boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
					//如果是单例的,会对参数进行空判断,并且只要有一个参数
					//为null,那么就不会再使用提供的参数,使用自动装配
					if (useArgs && beanFactory.isSingleton(beanName)) {
						// Stubbed null arguments just for reference purposes,
						// expecting them to be autowired for regular singleton references?
						// A safe assumption since @Bean singleton arguments cannot be optional...
						for (Object arg : beanMethodArgs) {
							if (arg == null) {
								useArgs = false;
								break;
							}
						}
					}
					//创建@Bean方法的返回对象
					Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
							beanFactory.getBean(beanName));
					//如果创建的bean实例不是@Bean方法的返回值实例,那么抛出错误。
					if (beanInstance != null && !ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
						String msg = String.format("@Bean method %s.%s called as a bean reference " +
									"for type [%s] but overridden by non-compatible bean instance of type [%s].",
									beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
									beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
						try {
							BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
							msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
						}
						catch (NoSuchBeanDefinitionException ex) {
							// Ignore - simply no detailed message then.
						}
						throw new IllegalStateException(msg);
					}
					return beanInstance;
				}
				finally {
				    //恢复正在创建状态
					if (alreadyInCreation) {
						beanFactory.setCurrentlyInCreation(beanName, true);
					}
				}
			}
		}
		
		
		//BeanFactoryAwareMethodInterceptor
		//这个拦截器只匹配setBeanFacctory方法
		private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {

		@Override
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		    //给方法设置BeanFactory
			Field field = obj.getClass().getDeclaredField(BEAN_FACTORY_FIELD);
			Assert.state(field != null, "Unable to find generated BeanFactory field");
			field.set(obj, args[0]);

			// Does the actual (non-CGLIB) superclass actually implement BeanFactoryAware?
			// If so, call its setBeanFactory() method. If not, just exit.
			//直接调用父类方法
			if (BeanFactoryAware.class.isAssignableFrom(obj.getClass().getSuperclass())) {
				return proxy.invokeSuper(obj, args);
			}
			return null;
		}

		@Override
		public boolean isMatch(Method candidateMethod) {
		    //只拦截setBeanFactory(BeanFactory bf)方法
			return (candidateMethod.getName().equals("setBeanFactory") &&
					candidateMethod.getParameterTypes().length == 1 &&
					BeanFactory.class == candidateMethod.getParameterTypes()[0] &&
					BeanFactoryAware.class.isAssignableFrom(candidateMethod.getDeclaringClass()));
		}
	}

    下面是增强逻辑中涉及的关系类图

在这里插入图片描述

    下面是增强逻辑中部分调用流程

在这里插入图片描述

    好了,到这里注解配置就宣告结束了。并且也宣告我们所有加载的BeanDefinition都已经准备好了,是时候可以进行bean的创建了,下面我们开始学习bean的创建。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值