Spring中Bean的实例化与DI的过程

引言

前文咱们介绍了关于如何学习Spring的源码以及解析了spring中加载配置文件注册Beandefinition的过程。今天咱们继续学习DI的过程。java

建立实例和DI过程

IOC和DI都是对spring容器特性的描述。IOC指的是将实例的生命周期交给第三方管理(spring)。而DI的侧重点在于某一个类依赖了其余的实例,将实例注入到依赖它的实例的过程。因此能够很明显的看出来DI是发生在类实例已经实例化完成以后的。spring

###建立实例api

BeanDefinition

BeanDefinition是对bean属性的定义,包含了bean的状态的属性,如bean的Class对象,单例仍是原型等。缓存

Beandefinition

上图中是BeanDefinition定义的方法,能够看出其中包括建立Bean的工厂类名称和bean的状态单例,懒加载等。bash

其中大多数方法都很容易理解,有几个属性这里须要解释下。markdown

dependsOn

dependsOn是指当前Beandefinition所表示的Bean依赖了其余那些bean(不包括基本数据类型),这里依赖的bean并不须要在当前Bean中声明,因此不能经过依赖注入完成,而是须要显示的定义。session

autowireCandidate

autowireCandidate用来表示当前bean是否能够被注入到其余实例中。mvc

上面的内容均可以经过xml配置或者注解来配置。app

xmljvm

<bean scope="singleton" autowire-candidate="true" init-method="" factory-method="" lazy-init="true" >
    </bean>
复制代码

注解

public class JavaBean {
    
    public void init(){
        //init
    }

    public void destroy(){
        //destroy
    }
    
    @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public JavaBean getEntity(){
        return new JavaBean();
    }
}
复制代码
继承体系

BeanDefinition继承体系

在上图中实际实际被用来实现Beandefinition的类是RootBeanDefinitionChildBeanDefinitionGenericBeanDefinition。其中GenericBeanDefinition是在spring2.5之后才出现的,spring2.5之后都建议使用GenericBeanDefinition。可是因为之前的代码都是使用RootBeanDefinitionChildBeanDefinition,因此咱们也还能看到RootBeanDefinitionChildBeanDefinition这些类。

大致流程

同IOC同样在阅读源码前先来看看一DI的大致流程。

DI流程

refresh()

在阅读IOC相关实现的时候,除开构造函数外refresh()就是咱们最初的入口,当时只是看了其中的部分代码。实际上refresh()贯穿了spring启动的整个阶段。当refresh()方法执行完成时基本就表明spring正常启动了。在DI篇咱们来继续看refresh()的其余的一些代码。

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
		    //读取配置文件 注册Beandefinition
			prepareRefresh();
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			prepareBeanFactory(beanFactory);

			try {

				postProcessBeanFactory(beanFactory);
				invokeBeanFactoryPostProcessors(beanFactory);

				registerBeanPostProcessors(beanFactory);

				initMessageSource();

				initApplicationEventMulticaster();

				onRefresh();

				registerListeners();

				finishBeanFactoryInitialization(beanFactory);

				finishRefresh();
			}catch (BeansException ex) {
				logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);

				destroyBeans();

				cancelRefresh(ex);
				throw ex;
			}
		}
	}
复制代码

BeanFactoryPostProcessor和BeanPostProcessor

在进行bean的实例化以前会先执行BeanFactoryPostProcessor和注册BeanPostProcessor

BeanFactoryPostProcessorBeanPostProcessor这两个接口为Spring的Bean后置处理器接口,做用是为Bean的初始化先后提供可扩展的空间。

BeanFactoryPostProcessor

public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
复制代码

BeanFactoryPostProcessor能够对BeanDefinition进行处理。BeanFactoryPostProcessor在容器实际实例化任何其它的bean以前读取bean的元数据,而且能够对其进行修改修改。用于在执行实例化bean以前进行调用。

BeanPostProcessor

public interface BeanPostProcessor {

	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
复制代码

实现BeanPostProcessor接口能够在Bean初始化的先后作一些自定义的操做,可是不可以直接操做BeanDefinition元数据。

BeanFactoryPostProcessorBeanPostProcessor都是spring留给咱们进行扩展的类。经过实现这两个接口咱们能够在bean的实例化过程当中添加一些自定义的操做。而须要注意的是这两个接口虽然都提供了扩展bean实例化的功能,但二者确实彻底不一样的:

  • BeanFactoryPostProcessor是在全部的bean都未开始实例化前调用,其能够拿到容器中全部的Beandefinition,因此能够在bean实例化前直接修改bean定义的元数据。
  • BeanPostProcessor里的实例化先后指的是调用init(init-method)方法先后,这时实际上bean已经开始了实例化(详细的能够参考类的实例化全过程),这时取到的仅仅是某一指定类的实例。即便进行修改也只是修改当前这一实例,而没法对bean的元数据修改。

因为postProcessor可能会在bean的实例化以前进行调用,因此在实例化前context确定须要先拿到postProcessor,这也就能够解释上面的代码中在解析完配置文件后就开始注册BeanFactoryPostProcessorBeanPostProcessor

listener

//tood

具体的关于postProcessor和Listener相关会在将总体流程理顺后再详细介绍。

finishBeanFactoryInitialization(ConfigurableListableBeanFactory)

finishBeanFactoryInitialization方法是对bean进行实例化的入口。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}
        
		beanFactory.setTempClassLoader(null);
		//缓存bean定义
		beanFactory.freezeConfiguration();
		beanFactory.preInstantiateSingletons();
	}
复制代码

方法首先查找是否开启了注册conversionService,conversionService是用于进行两个类转换的,例如以前说过了Environment类就依赖该实例将定义的变量转换为相应的类型。

若是要开启注册conversionService,能够在配置文件中配置。

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
	<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
	//property
	</bean>
复制代码

接下来的代码是从bean定义中获取LoadTimeWeaverAware类型优先进行实例化。LoadTimeWeaverAware做用是当类被加载进jvm是动态的转换类。之因此优先实例化这些类是由于在实例化其余类时可能会使用到这些类,好比jpa就极度依赖这些功能。

preInstantiateSingletons()

public void preInstantiateSingletons() throws BeansException {
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

		for (String beanName : beanNames) {
		    //获取bean定义
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//抽象类没法实例化
			//非单例和懒加载在须要时才实例化
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
				    //获取factoryBean的实例
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}else {
					getBean(beanName);
				}
			}
		}

		// 实现了SmartInitializingSingleton接口的回调方法
		// SmartInitializingSingleton接口同InitializingBean接口相似都是用于在建立bean时进行一些后置的操做 
		// 不一样之处在于InitializingBean是在每个实例化的过程当中进行调用 而SmartInitializingSingleton是在全部的单例bean被实例化后再refresh中进行回调
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							smartSingleton.afterSingletonsInstantiated();
							return null;
						}
					}, getAccessControlContext());
				}else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}
复制代码

preInstantiateSingletons经过一个for循环来实例化全部注册到容器中的bean定义所表明的的bean。

在肯定好每个beanName所表明的的bean确实须要实例化后首先检查当前beanName是否实现了接口 FactoryBeanFactoryBean是一种产生bean的bean,至关于一个bean工厂。实现FactoryBean接口容许咱们生产一个具备特色类型和参数的bean,其本质上和经过xml配置实例化的bean没有区别,好处在于对于复杂对象能够代替xml中繁杂的配置项,仅经过java代码实现。

而因为FactoryBean自己首先是一个bean,因此咱们也能够在ioc容器中获取该bean的实例。若是咱们经过getBean(beanName)方法获取的其实是FactoryBean产生的实例类型,想要获取FactoryBean的实例须要使用getBean("&" + beanName)

getBean(String)

getBean是一个重载方法,主要仍是调用doGetBean()方法实现功能。

protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
        //取该beanName在容器中保存的name
        //好比上面介绍的factoryBean会加一个& 以及给bean配置的别名等
		final String beanName = transformedBeanName(name);
		Object bean;
        //尝试从保存bean的容器中取,若是已经存在则不用再次实例化
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}else {
            //对于非单例bean 若是该bean正在被建立而又尝试再次建立则会直接抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			    //!containsBeanDefinition(beanName)表示从当前容器中没有找到匹配的BeanDefinition 尝试从父容器中查找
				String nameToLookup = originalBeanName(name);
				if (args != null) {
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}else {
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			if (!typeCheckOnly) {
			    //标记当前beanName所表示的bean正在被建立或已经被建立
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//这一步根据其实现貌似主要是检查当前BeanDefinition表示的bean是不是一个抽象类,可是前面已经检查过了 这里再次检查貌似意义不大
				checkMergedBeanDefinition(mbd, beanName, args);
				
				//检查是否配置了bean的依赖 若是存在则须要先实例化被依赖的bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dependsOnBean : dependsOn) {
						if (isDependent(beanName, dependsOnBean)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
						}
						registerDependentBean(dependsOnBean, beanName);
						getBean(dependsOnBean);
					}
				}

				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
							@Override
							public Object getObject() throws BeansException {
								beforePrototypeCreation(beanName);
								try {
									return createBean(beanName, mbd, args);
								}
								finally {
									afterPrototypeCreation(beanName);
								}
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; " +
								"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type [" +
							ClassUtils.getQualifiedName(requiredType) + "]", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}
复制代码

方法中的try-catch块用于建立bean实例,代码不少,不过只是根据bean的做用范围来进行建立如Singleton,prototype或者session等。建立bean的过程大同小异,区别仅在与实例保存的地方。单例bean被保存在一个map中,整个程序运行期间有效。原型bean保存在另外的容器中,每一次使用时须要从新建立。

以单例bean建立过程为例,主要实现过程都在getSingleton(...)方法中了。getSingleton(...)的主要功能就是检查bean是否已经建立,若是没建立就进行建立而后保存到容器中。建立bean的过程由一个匿名内部类实现。

createBean(String beanName, RootBeanDefinition mbd, Object[] args)

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {

		resolveBeanClass(mbd, beanName);
		try {
			mbd.prepareMethodOverrides();
		}catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
		    //首先尝试执行BeanPostProcessor,若是存在后置处理器 那么首先实例化bean执行处理器
			Object bean = resolveBeforeInstantiation(beanName, mbd);
			if (bean != null) {
				return bean;
			}
		}catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
        //不存在后置处理器或者存在的执行处理器过程建立实例失败或没有建立实例的动做则执行下面的方法
		Object beanInstance = doCreateBean(beanName, mbd, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
复制代码

上面方法中有这样一句mbd.prepareMethodOverrides()methodOverrides实际上市BeanDefinition中的一个属性。其主要用于记录在配置文件中lookup-method和replaced-method参数设置的值。详情能够看这里:methodOverrides

doCreateBean(...)

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
		    //若是已经实例化须要从新实例化则从缓存中删除 从新设置
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//more code
	}
复制代码

方法开头显示建立了一个BeanWrapper的对象,BeanWrapper至关于一个代理器,Spring委托BeanWrapper来完成bean内部属性的初始化。

上述方法代码不少,在建立阶段只须要关注前几行。若是该bean的实例未被建立则直接建立一个。建立的方法有createBeanInstance完成。

createBeanInstance(...)

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
        //判断当前bean类是否被定义为public 非public的类没法在其余类中实例化
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}
		return instantiateBean(beanName, mbd);
	}
复制代码

该方法先是尝试查看是否配置了工厂方法,若是存在工厂方法则由工厂方法进行建立。

接下来的几行代码是用来提高性能的。spring在建立实例后会将建立该实例的constructor方法缓存,这样下一次须要建立该bean时直接取出构造方法建立便可不须要再从新解析一次。

若是没有工厂方法而且构造方法也没有缓存,同时没有找到有参的构造函数,那么会经过放射调用类的默认无参构造函数。

instantiateBean(String, RootBeanDefinition)

该实例化方法没有太多解析的必要,基本就是经过反射的原理获取无参构造函数,经过构造函数来实例化类。

DI

到这里为止建立一个实例的过程就完成了,接下来就是检查该实例是否须要被注入其余的属性了。

回到doCreateBean(...)

前面在建立bean实例时调用到了doCreateBean(...)方法,在建立好实例后的后续功能也依赖于该方法。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
        // other-code
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		} catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}
		// other-code
		return exposedObject;
	}
复制代码

在DI阶段咱们须要关注的就上上面的代码,首先是经过populateBean方法对在配置文件中配置的property属性进行设置值。

populateBean顾名思义就是对bean中的属性添加数据。populateBean中实际上是经过后置处理器来进行属性的设置,主要的代码以下:

PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
			if (pvs == null) {
				return;
			}
		}
	}
}
复制代码

spring中默认注册了如下几种beanPostProcessor,以下:

beanPostProcessor

每个beanPostProcessor都会在实例化先后相应的地方进行调用。在这里咱们须要关注的是AutowiredAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor这几个注解。

顾名思义这几个beanPostProcessor都是用来处理注解的,对应用来处理@Autowired,@Required,@Common几个注解。

这里以@Autowored的处理为例。

AutowiredAnnotationBeanPostProcessor

public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
		try {
			metadata.inject(bean, beanName, pvs);
		}catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}
	
	private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
		LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
		Class<?> targetClass = clazz;

		do {
			LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
			for (Field field : targetClass.getDeclaredFields()) {
				AnnotationAttributes annotation = findAutowiredAnnotation(field);
				if (annotation != null) {
					if (Modifier.isStatic(field.getModifiers())) {
						if (logger.isWarnEnabled()) {
							logger.warn("Autowired annotation is not supported on static fields: " + field);
						}
						continue;
					}
					boolean required = determineRequiredStatus(annotation);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			}
			for (Method method : targetClass.getDeclaredMethods()) {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					continue;
				}
				AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
				if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (Modifier.isStatic(method.getModifiers())) {
						if (logger.isWarnEnabled()) {
							logger.warn("Autowired annotation is not supported on static methods: " + method);
						}
						continue;
					}
					if (method.getParameterTypes().length == 0) {
						if (logger.isWarnEnabled()) {
							logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
						}
					}
					boolean required = determineRequiredStatus(ann);
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					currElements.add(new AutowiredMethodElement(method, required, pd));
				}
			}
			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return new InjectionMetadata(clazz, elements);
	}
复制代码

该方法主要就是经过解析当前bean有哪些属性被@Autowired注解修饰,将其封装为一个InjectionMetadata对象。解析的过程经过findAutowiringMetadata(String beanName, Class<?> clazz)完成,但实际上主要仍是经过上面的buildAutowiringMetadata(Class<?> clazz)完成。

方法比较简单,首先就是遍历bean的全部字段(Field),经过反射的方法查找字段上的注解,若是存在匹配的注解(AutowiredAnnotationBeanPostProcessor匹配的就是@Autowired)。若是存在该注解就将这个字段记录表示须要进行注入。

当将字段遍历完成后就取出全部的方法,查找方法上是否有该注解,若是存在的话同理记录下该方法。

对于被记录下的字段或者方法会被封装成一个InjectedElement对象。经过该对象的inject方法完成注入工做。

protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
		Field field = (Field) this.member;
		try {
			Object value;
			if (this.cached) {
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			} else {
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				synchronized (this) {
					if (!this.cached) {
						if (value != null || this.required) {
							this.cachedFieldValue = desc;
							registerDependentBeans(beanName, autowiredBeanNames);
							if (autowiredBeanNames.size() == 1) {
								String autowiredBeanName = autowiredBeanNames.iterator().next();
								if (beanFactory.containsBean(autowiredBeanName)) {
									if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
										this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);
									}
								}
							}
						} else {
							this.cachedFieldValue = null;
						}
						this.cached = true;
					}
				}
			}
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		} catch (Throwable ex) {
			throw new BeanCreationException("Could not autowire field: " + field, ex);
		}
	}
}
复制代码

刚方法整体来讲比较简单,首先是查询当前bean的依赖是否已经被缓存,若是缓存了则从缓存中取便可。

若是是第一次解析则从beanfactory中获取相应的依赖属性。

synchronized代码块主要就是将解析后的依赖的值缓存起来,创建当前bean和其依赖的属性之间的关系。当下一次建立该类型的bean时能够直接使用不需从新解析。

而真正的属性注入是依赖着几行代码:

if (value != null) {
	ReflectionUtils.makeAccessible(field);
	field.set(bean, value);
}
复制代码

上面的代码没有任何的难度,就是对JDK中反射的api的使用。

基本上后面就是重复这个过程对bean的属性进行注入,在这一过程当中最重要的就是beanPostProcessor,注入都已依赖这一组完成的。

相关文章
相关标签/搜索