Spring源码解读4——依赖注入的发生

依赖注入在以下两种情况发生:

(1).用户第一次通过getBean方法向IoC容索要Bean时,IoC容器触发依赖注入。

(2).当用户在Bean定义资源中为<Bean>元素配置了lazy-init属性,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入。

public abstract class AbstractBeanFactory{

        public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly){
                //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖 
		final String beanName = transformedBeanName(name);
		Object bean;
                //先从缓存中取是否已经有被创建过的单态类型的Bean
                Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			......
                        //如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回 
                        //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理  
                        //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是  
                        //创建创建对象的工厂Bean,两者之间有区别  
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {//缓存没有正在创建的单态模式Bean  
                        ......
                        //根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类合并父类公共属性问题

                        //***这个getMergedLocalBeanDefinition(beanName)肯定是在获取注册过的BeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                        //创建单态模式Bean的实例对象
			if (mbd.isSingleton()) {
                                //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
				sharedInstance = getSingleton(beanName, new ObjectFactory() {
					public Object getObject() throws BeansException {
						try {
							return createBean(beanName, mbd, args);
						}
					}
				});
                                //获取给定Bean的实例对象
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
                        //IoC容器创建原型模式Bean实例对象
			else if (mbd.isPrototype()) {
				//原型模式(Prototype)是每次都会创建一个新的对象 
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
                                 //获取给定Bean的实例对象
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
                        //要创建的Bean既不是单态模式,也不是原型模式,则根据Bean定义资源中  
                        //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中  
                        //比较常用,如:request、session、application等生命周期  
			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() {
						public Object getObject() throws BeansException {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						}
					});
                                        //获取给定Bean的实例对象 
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}

			}
                return (T) bean;
		}
                
}

上面的源码只是定义了根据Bean定义的模式,采取的不同创建Bean实例对象的策略,具体的Bean实例对象的创建过程由实现了ObejctFactory接口的匿名内部类的createBean方法完成,ObejctFactory使用委派模式,具体的Bean实例创建过程交由其实现类AbstractAutowireCapableBeanFactory完成,我们继续分析AbstractAutowireCapableBeanFactory的createBean方法的源码

public class AbstractAutowireCapableBeanFactory{
	protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args){

                 Object beanInstance = doCreateBean(beanName, mbd, args);
                 return beanInstance;
        }

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
                //封装被创建的Bean对象
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {//单态模式的Bean,先从容器中缓存中获取同名Bean
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
                        //创建实例对象 
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
                final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
                //Bean对象的初始化,依赖注入在此触发  
                //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
		Object exposedObject = bean;
		try {
                        //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
                                //在对Bean实例对象生成和依赖注入完成以后,开始对Bean实例对象
                                //进行初始化,为Bean实例对象应用BeanPostProcessor后置处理器
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
                ......
                return exposedObject; 

        } 
   
        //通过对方法源码的分析,我们看到具体的依赖注入实现在以下两个方法中:
        //(1).createBeanInstance:生成Bean所包含的java对象实例。
        //(2).populateBean :对Bean属性的依赖注入进行处理。

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class beanClass = resolveBeanClass(mbd, beanName);
                //使用工厂方法对Bean进行实例化
		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);
			}
		}

		//使用Bean的构造方法进行实例化 
		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);

        }
        //使用默认的无参构造方法实例化 
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
                Object beanInstance;
                //方法getInstantiationStrategy().instantiate调用了SimpleInstantiationStrategy类中的实例化Bean的方法
                //方法中使用反射取得构造函数进行实例化
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
                BeanWrapper bw = new BeanWrapperImpl(beanInstance);  
                initBeanWrapper(bw);  
                return bw; 

        }

方法getInstantiationStrategy().instantiate调用了SimpleInstantiationStrategy类中的实例化Bean的方法

public class SimpleInstantiationStrategy implements InstantiationStrategy {

	public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
		//如果Bean定义中没有方法覆盖,则就不需要CGLIB父类类的方法
		if (beanDefinition.getMethodOverrides().isEmpty()) {
			Constructor<?> constructorToUse;
			synchronized (beanDefinition.constructorArgumentLock) {
                                //获取对象的构造方法或工厂方法
				constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
                                //如果没有构造方法且没有工厂方法
				if (constructorToUse == null) {

                                        //获取BeanDefinition中的class路径
					final Class clazz = beanDefinition.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
                                                        //这里是一个匿名内置类,使用反射机制获取Bean的构造方法
							constructorToUse = AccessController.doPrivile(new
PrivilegedExceptionAction<Constructor>() {
								public Constructor run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Exception ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
                        //使用BeanUtils实例化,通过反射机制调用”构造方法.newInstance(arg)”来进行实例化
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			//使用CGLIB来实例化对象
			return instantiateWithMethodInjection(beanDefinition, beanName, owner);
		}
	}
}

(1).createBeanInstance:生成Bean所包含的java对象实例。已经分析完。这里返回的实例是空的,需要注入属性。

(2).populateBean :对Bean属性的依赖注入进行处理。开始一分析:

protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
                //获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
		PropertyValues pvs = mbd.getPropertyValues();       
                //依赖注入开始,首先处理autowire自动装配的注入 
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
                ... ...

                //对属性进行注入  
		applyPropertyValues(beanName, mbd, bw, pvs);
        }

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
                 //属性值已经转换
		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
                                        //为实例化对象设置属性值  
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
                        //获取属性值对象的原始类型值 
			original = mpvs.getPropertyValueList();
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}
                //为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中(解析过的属性都放进这个拷贝中,最后再将
                //拷贝注入进Bean里)  
		List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
                                //转换属性值,例如将引用转换为IoC容器中实例化对象引用  
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                                ......
                        }
                ......
                bw.setPropertyValues(new MutablePropertyValues(deepCopy)); 
        }
	public Object resolveValueIfNecessary(Object argName, Object value) {......}

}

依赖注入是通过bw.setPropertyValues方法实现的,该方法也使用了委托模式,在BeanWrapper接口中至少定义了
方法声明,依赖注入的具体实现交由其实现类BeanWrapperImpl来完成

//AbstractPropertyAccessor类是BeanWrapperImpl的父类,setPropertyValue采用模板模式,由子类BeanWrapperImpl实现。
public abstract class AbstractPropertyAccessor{
	public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
			throws BeansException {

		List<PropertyAccessException> propertyAccessExceptions = null;
		List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
				((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));

                //pvs里有很多值,故要循环注入
		for (PropertyValue pv : propertyValues) {
			try {
				// This method may throw any BeansException, which won't be caught
				// here, if there is a critical failure such as no matching field.
				// We can attempt to deal only with less serious exceptions.
				setPropertyValue(pv);
			}
		}
}
public class BeanWrapperImpl{
	public void setPropertyValue(PropertyValue pv){

                PropertyDescriptor pd = pv.resolvedDescriptor;  
                Object originalValue = pv.getValue();  
                Object valueToApply = originalValue; 
                //根据JDK的内省机制,获取属性的setter(写方法)方法  
                final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ?  
                        ((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() :  
                        pd.getWriteMethod());  
                //如果属性的setter方法是非public,即访问控制权限比较严格,则使用JDK的反射机制,  
                //强行设置setter方法可访问(暴力为属性赋值)  
                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {  
                    //如果使用了JDK的安全机制,则需要权限验证  
                    if (System.getSecurityManager()!= null) {  
                        AccessController.doPrivileged(new PrivilegedAction<Object>() {  
                            public Object run() {  
                                writeMethod.setAccessible(true);  
                                return null;  
                            }  
                        });  
                    }  
                    else {  
                        writeMethod.setAccessible(true);  
                    }  
                }  
                final Object value = valueToApply;  
                if (System.getSecurityManager() != null) {  
                    try {  
                        //将属性值设置到属性上去  
                        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {  
                            public Object run() throws Exception {  
                                writeMethod.invoke(object, value);  
                                return null;  
                            }  
                        }, acc);  
                    }  
                    catch (PrivilegedActionException ex) {  
                        throw ex.getException();  
                    }  
                } 
        }
}

 

转载于:https://my.oschina.net/u/2286010/blog/707213

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值