IOC容器的依赖注入
- 依赖注入发生的时间
当Spring IoC容器完成了Bean定义资源的定位、载入和解析注册以后,IoC容器中已经管理类Bean定义的相关数据,但是此时IoC容器还没有对所管理的Bean进行依赖注入,依赖注入在以下两种情况发生:
(1).用户第一次通过getBean方法向IoC容索要Bean时,IoC容器触发依赖注入。
(2).当用户在Bean定义资源中为<Bean>元素配置了lazy-init属性,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入。
//获取IOC容器中一个指定名称的Bean
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
//获取IOC容器中一个指定类型的Bean
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
//获取IoC容器中指定名称和参数的Bean
public Object getBean(String name, Object[] args) throws BeansException {
return doGetBean(name, null, args, false);
}
//获取IoC容器中指定名称、类型和参数的Bean
public <T> T getBean(String name, Class<T> requiredType, Object[] args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
//真正获取Bean的地方
protected <T> T doGetBean(String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly)
throws BeansException
{
//如果指定的是别名,将别名转换为规范的Bean名称
String beanName = transformedBeanName(name);
//先从缓存中取是否已经有被创建过的单态类型的Bean,对于单态模式的Bean整个IoC容器中只创建一次,不需要重复创建
Object sharedInstance = getSingleton(beanName);
Object bean;
//IoC容器创建单态模式Bean实例对象
if ((sharedInstance != null) && (args == null)) {
if (this.logger.isDebugEnabled()) {
//如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回
//已经创建的Bean
if (isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug(new StringBuilder().append("Returning eagerly cached instance of singleton bean '").append(beanName).append("' that is not fully initialized yet - a consequence of a circular reference").toString());
}
else
{
this.logger.debug(new StringBuilder().append("Returning cached instance of singleton bean '").append(beanName).append("'").toString());
}
}
//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
//注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是创建创建对象的工厂Bean,两者之间有区别
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else
{
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//获取父容器
BeanFactory parentBeanFactory = getParentBeanFactory();
//父容器不为空并且在当前容器中没有指定名称的bean
if ((parentBeanFactory != null) && (!(containsBeanDefinition(beanName))))
{
//解析指定Bean名称的原始名称
String nameToLookup = originalBeanName(name);
if (args != null)
{
//委派父级容器根据指定名称和显式的参数查找bean
return parentBeanFactory.getBean(nameToLookup, args);
}else{
//委派父级容器根据指定名称和类型查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//创建的Bean是否需要进行类型验证,一般不需要
if (!(typeCheckOnly)) {
//向容器标记指定的Bean已经被创建
markBeanAsCreated(beanName);
}
try
{
//根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类
//合并父类公共属性问题
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean有依赖Bean
if (dependsOn != null)
for (String dependsOnBean : dependsOn) {
if (isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, new StringBuilder().append("Circular depends-on relationship between '").append(beanName).append("' and '").append(dependsOnBean).append("'").toString());
}
//把被依赖Bean注册给当前依赖的Bean
registerDependentBean(dependsOnBean, beanName);
//递归调用getBean方法,获取当前Bean的依赖Bean
getBean(dependsOnBean);
}
Object bean;
//如果Bean是单态的
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, new ObjectFactory(beanName, mbd, args)
{
public Object getObject() throws BeansException {
try {
//创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
return AbstractBeanFactory.this.createBean(this.val$beanName, this.val$mbd, this.val$args);
}
catch (BeansException ex)
{
//显式地从容器单态模式Bean缓存中清除实例对象
AbstractBeanFactory.this.destroySingleton(this.val$beanName);
throw ex;
}
}
});
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else
{
Object bean;
//IoC容器创建原型模式Bean实例对象
if (mbd.isPrototype())
{
//原型模式(Prototype)是每次都会创建一个新的对象
Object prototypeInstance = null;
try {
//回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
beforePrototypeCreation(beanName);
//创建指定Bean对象实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else
{
//要创建的Bean既不是单态模式,也不是原型模式,则根据Bean定义资源中
//配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
//比较常用,如:request、session、application等生命周期
String scopeName = mbd.getScope();
//Bean定义资源中没有配置生命周期范围,则Bean定义不合法
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null)
throw new IllegalStateException(new StringBuilder().append("No Scope registered for scope '").append(scopeName).append("'").toString());
Object bean;
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);
}
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);
}
}
}
//对创建的Bean实例对象进行类型检查
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return (T) bean;
}
通过上面对向IoC容器获取Bean方法的分析,我们可以看到在Spring中,如果Bean定义的单态模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象。如果Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。除此之外,Bean定义还可以扩展为指定其生命周期范围。
上面的源码只是定义了根据Bean定义的模式,采取的不同创建Bean实例对象的策略,具体的Bean实例对象的创建过程由实现了ObejctFactory接口的匿名内部类的createBean方法完成,ObejctFactory使用委派模式,具体的Bean实例创建过程交由其实现类AbstractAutowireCapableBeanFactory完成。
@Override
//创建Bean实例
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
resolveBeanClass(mbd, beanName);
//校验和准备Bean中的方法覆盖
try {
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建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);
}
//创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//创建Bean实例
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
//封装被创建的Bean对象
BeanWrapper instanceWrapper = null;
//单态模式的Bean,先从容器中缓存中获取同名Bean
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//如果不存在单态的Bean
if (instanceWrapper == null) {
//则创建Bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//获取实例化Bean
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
//获取实例化Bean的类型
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
//调用PostProcessor后置处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
//向容器中缓存单态模式的Bean对象,以防循环引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//Bean对象的初始化,依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try {
//将Bean实例对象封装,并且将Bean定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//初始化依赖注入的Bean对象
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);
}
}
if (earlySingletonExposure) {
//获取指定名称的已注册的单态模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
exposedObject = earlySingletonReference;
}
//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
//获取当前Bean所依赖的其他Bean
for (String dependentBean : dependentBeans) {
//对依赖Bean进行类型检查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
//注册完成依赖注入的Bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
(1)createBeanInstance:生成Bean所包含的java对象实例
(2)populateBean :对Bean属性的依赖注入进行处理
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//检查确认Bean是可实例化的
Class<?> beanClass = resolveBeanClass(mbd, beanName);
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) {
//容器的自动装配是根据参数类型匹配Bean的构造方法
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);
}
//使用无参构造实例化Bean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
//获取系统的安全管理接口,JDK标准的安全管理API
if (System.getSecurityManager() != null) {
//这里是一个匿名内置类,根据实例化策略创建实例对象
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
//根据实例化策略创建实例对象
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//将实例化的对象封装起来
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
//初始化Bean对象
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
可以看出在createBeanInstance对于实例化Bean是使用工厂方法还是自动装配已经非常清楚,根据不同的配置选择调用工厂方法或者在开启自动装配的情况下调用相应的构造方法或者使用默认的无参构造就可以实例化对象了,对于我们经常使用的无参构造实例化对象需要使用相应的初始化策略进行Bean的实例化,getInstantiationStrategy().instantiate(mbd, beanName, parent)选择不同的实例化策略来完成对Bean的初始化.最终BeanWapper完成对Bean的封装。
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
//判读是否使用Cglib实例化对象
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
//获取对象的构造方法或工厂方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
//如果没有构造方法且没有工厂方法
if (constructorToUse == null) {
//判断实例化的Bean是否是接口
final Class<?> clazz = bd.getBeanClass();
//接口无法实例化
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
//获取默认的构造函数
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//使用BeanUtils实例化对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 使用Cjlib实例化对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
SimpleInstantiationStrategy中会判断使用何种方式来实例化对象。
当使用cglib代理时:
//传入构造器和构造器参数
public Object instantiate(Constructor<?> ctor, Object... args) {
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
//判断是否有无参构造
if (ctor == null) {
//使用无参构造实例化
instance = BeanUtils.instantiate(subclass);
}
else {
try {
//使用有参构造实例化
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
//使用Cglib代理
private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
Enhancer enhancer = new Enhancer();
//当前Bean作为基类
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
enhancer.setCallbackTypes(CALLBACK_TYPES);
return enhancer.createClass();
}
}
到此实例化对象完成。
接下来看是如何对Bean的属性进行依赖注入处理的
populateBean :对Bean属性的依赖注入进行处理
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
///获得bean封装的属性值
PropertyValues pvs = mbd.getPropertyValues();
//如果实例化beannull
if (bw == null) {
//属性值不为null
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
//实例化对象为null 属性值也为null
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
//如果是自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
//将需要注入的属性封装
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//对autowire自动装配的处理,根据Bean名称自动装配注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//对autowire自动装配的处理,根据Bean类型自动装配注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//检查容器是否持有用于处理单态模式Bean关闭时的后置处理器
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//Bean实例对象没有依赖,即没有继承基类
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//使用BeanPostProcessor处理器处理属性值
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
//对注入的属性进行依赖检查
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//对属性进行注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
//判断属性值是否封装
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);
}
}
//否则获得BeanDefinition的原始参数集合
original = mpvs.getPropertyValueList();
}
else {
//属性值未封装获得BeanDefinition的原始参数集合
original = Arrays.asList(pvs.getPropertyValues());
}
//获取用户自定义的类型转换
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//创建一个Bean定义属性值解析器,将Bean定义中的属性值解析为Bean实例对象的实际值
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
//为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
//属性值不需要转换
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
//原始的属性值,即转换之前的属性值
Object originalValue = pv.getValue();
//转换属性值,例如将引用转换为IoC容器中实例化对象引用
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
//转换之后的属性值
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
//标记属性值已经完成转换
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
//进行属性的依赖注入
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
在进行依赖注入的时候会首先检查Bean的实例对象是否创建,然后会检查BeanDefinition是否配置了自动装配的属性,是按照名称自动注入
Autowire=byName 还是Autowire=byType,进行自动装配的处理,当然在自动装配的时候会首先封装需要注入的属性。关于如何自动装配也是我们比较关心的事情。到了这里需要注入的属性已经完全获取完成,但是获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中,例如Bean对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入。
//对属性值进行解析
public Object resolveValueIfNecessary(Object argName, Object value) {
//如果属性值是引用对象
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
//使用解析引用对象的方法
return resolveReference(argName, ref);
}
//如果对属性值是引用容器中另一个Bean名称
if (value instanceof RuntimeBeanNameReference) {
//获取引用对象名称
String refName = ((RuntimeBeanNameReference) value).getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (!(this.beanFactory.containsBean(refName))) {
throw new BeanDefinitionStoreException(new StringBuilder().append("Invalid bean name '").append(refName)
.append("' in bean reference for ").append(argName).toString());
}
return refName;
}
//对Bean类型属性的解析,主要是Bean中的内部类
if (value instanceof BeanDefinitionHolder) {
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
if (value instanceof BeanDefinition) {
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = new StringBuilder().append("(inner bean)#")
.append(ObjectUtils.getIdentityHexString(bd)).toString();
return resolveInnerBean(argName, innerBeanName, bd);
}
String elementTypeName;
//对集合数组类型的属性解析
if (value instanceof ManagedArray) {
ManagedArray array = (ManagedArray) value;
//获取数组的类型
Class elementType = array.resolvedElementType;
if (elementType == null) {
//获取数组元素的类型
elementTypeName = array.getElementTypeName();
if (StringUtils.hasText(elementTypeName)) {
try {
//使用反射机制创建指定类型的对象
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
array.resolvedElementType = elementType;
} catch (Throwable ex) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,
new StringBuilder().append("Error resolving array type for ").append(argName)
.toString(),
ex);
}
} else {
//没有获取到数组的类型,也没有获取到数组元素的类型,则直接设置数组的类型为Object
elementType = Object.class;
}
}
//创建指定类型的数组
return resolveManagedArray(argName, (List) value, elementType);
}
//解析list类型的属性值
if (value instanceof ManagedList) {
return resolveManagedList(argName, (List) value);
}
//解析set类型的属性值
if (value instanceof ManagedSet) {
return resolveManagedSet(argName, (Set) value);
}
//map
if (value instanceof ManagedMap) {
return resolveManagedMap(argName, (Map) value);
}
//解析props类型的属性值,props其实就是key和value均为字符串的map
if (value instanceof ManagedProperties) {
Properties original = (Properties) value;
//创建一个拷贝,用于作为解析后的返回值
Properties copy = new Properties();
for (Map.Entry propEntry : original.entrySet()) {
Object propKey = propEntry.getKey();
Object propValue = propEntry.getValue();
if (propKey instanceof TypedStringValue) {
propKey = evaluate((TypedStringValue) propKey);
}
if (propValue instanceof TypedStringValue) {
propValue = evaluate((TypedStringValue) propValue);
}
copy.put(propKey, propValue);
}
return copy;
}
//解析字符串类型的属性值
if (value instanceof TypedStringValue) {
TypedStringValue typedStringValue = (TypedStringValue) value;
Object valueObject = evaluate(typedStringValue);
try {
//获取属性的目标类型
Class resolvedTargetType = resolveTargetType(typedStringValue);
//对目标类型的属性进行解析,递归调用
if (resolvedTargetType != null) {
return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
}
//没有获取到属性的目标对象,则按Object类型返回
return valueObject;
} catch (Throwable ex) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,
new StringBuilder().append("Error converting typed String value for ").append(argName)
.toString(),
ex);
}
}
//解析引用对象
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
//获取引用对象的Bean名称
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
//如果引用的对象在父类容器中,则从父类容器中获取指定的引用对象
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,
new StringBuilder().append("Can't resolve reference to bean '").append(refName)
.append("' in parent factory: no parent factory available").toString());
}
return this.beanFactory.getParentBeanFactory().getBean(refName);
}
//从当前容器获取bean
Object bean = this.beanFactory.getBean(refName);
//注册依赖对象
this.beanFactory.registerDependentBean(refName, this.beanName);
return bean;
} catch (BeansException ex) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName,
new StringBuilder().append("Cannot resolve reference to bean '").append(ref.getBeanName())
.append("' while setting ").append(argName).toString(),
ex);
}
}
return evaluate(value);
}
//解析字符串
protected Object evaluate(Object value) {
//如果是字符串
if (value instanceof String) {
return doEvaluate((String) value);
}
//如果是字符串数组
if (value instanceof String[]) {
String[] values = (String[]) (String[]) value;
//标记已经被解析
boolean actuallyResolved = false;
//创建一个等长的数组
Object[] resolvedValues = new Object[values.length];
for (int i = 0; i < values.length; ++i) {
String originalValue = values[i];
//解析
Object resolvedValue = doEvaluate(originalValue);
//证明解析过
if (resolvedValue != originalValue) {
actuallyResolved = true;
}
resolvedValues[i] = resolvedValue;
}
//根据是否解析过返回
return ((actuallyResolved) ? resolvedValues : values);
}
需要指明的是IOC容器中的BeanDefinitionHolr中封装了beand的id 别名和BeanDefinition,而BeanDefinition则封装了Bean的其他属性.自此属性值的解析全部完成,下一步准备注入
public void setPropertyValue(PropertyValue pv) throws BeansException {
PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
if (tokens == null) {
String propertyName = pv.getName();
BeanWrapperImpl nestedBw;
try {
nestedBw = getBeanWrapperForPropertyPath(propertyName);
} catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
new StringBuilder().append("Nested property in path '").append(propertyName)
.append("' does not exist").toString(),
ex);
}
BeanWrapperImpl nestedBw;
tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
if (nestedBw == this) {
pv.getOriginalPropertyValue().resolvedTokens = tokens;
}
nestedBw.setPropertyValue(tokens, pv);
} else {
setPropertyValue(tokens, pv);
}
}
private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
//PropertyTokenHolder用于保存属性的名称还有集合属性的siez
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
//如果集合属性不为null 先注入集合属性
if (tokens.keys != null) {
//创建一份PropertyTokenHolder拷贝
PropertyTokenHolder getterTokens = new PropertyTokenHolder(null);
getterTokens.canonicalName = tokens.canonicalName;
getterTokens.actualName = tokens.actualName;
getterTokens.keys = new String[tokens.keys.length - 1];
System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
Object propValue;
try {
//通过JDK内省获得属性值,必须有Getter(readerMethod)方法,获取属性的值
propValue = getPropertyValue(getterTokens);
} catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
new StringBuilder()
.append("Cannot access indexed value in property referenced in indexed property path '")
.append(propertyName).append("'").toString(),
ex);
}
Object propValue;
//获取集合类型属性的长度
String key = tokens.keys[(tokens.keys.length - 1)];
//如果属性值为null
if (propValue == null) {
if (isAutoGrowNestedPaths()) {
int lastKeyIndex = tokens.canonicalName.lastIndexOf(91);
getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
propValue = setDefaultValue(getterTokens);
} else {
throw new NullValueInNestedPathException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
new StringBuilder()
.append("Cannot access indexed value in property referenced in indexed property path '")
.append(propertyName).append("': returned null").toString());
}
}
//集合类型的属性值
if (propValue.getClass().isArray()) {
//获取属性的描述符
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
//获得数组类型
Class requiredType = propValue.getClass().getComponentType();
//获得数组的长度
int arrayIndex = Integer.parseInt(key);
Object oldValue = null;
try {
//获取数组以前初始化的值
if ((isExtractOldValueForEditor()) && (arrayIndex < Array.getLength(propValue))) {
oldValue = Array.get(propValue, arrayIndex);
}
//获取解析后的属性值
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType,
TypeDescriptor.nested(property(pd), tokens.keys.length));
int length = Array.getLength(propValue);
if ((arrayIndex >= length) && (arrayIndex < this.autoGrowCollectionLimit)) {
Class componentType = propValue.getClass().getComponentType();
Object newArray = Array.newInstance(componentType, arrayIndex + 1);
System.arraycopy(propValue, 0, newArray, 0, length);
setPropertyValue(actualName, newArray);
propValue = getPropertyValue(actualName);
}
//设置集合的值
Array.set(propValue, arrayIndex, convertedValue);
} catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
new StringBuilder().append("Invalid array index in property path '").append(propertyName)
.append("'").toString(),
ex);
}
//注入list类型的属性值
} else if (propValue instanceof List) {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
Class requiredType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(),
tokens.keys.length);
List list = (List) propValue;
int index = Integer.parseInt(key);
Object oldValue = null;
if ((isExtractOldValueForEditor()) && (index < list.size())) {
oldValue = list.get(index);
}
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType,
TypeDescriptor.nested(property(pd), tokens.keys.length));
int size = list.size();
if ((index >= size) && (index < this.autoGrowCollectionLimit)) {
for (int i = size; i < index; ++i) {
try {
list.add(null);
} catch (NullPointerException ex) {
throw new InvalidPropertyException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
new StringBuilder().append("Cannot set element with index ").append(index)
.append(" in List of size ").append(size)
.append(", accessed using property path '").append(propertyName)
.append("': List does not support filling up gaps with null elements")
.toString());
}
}
list.add(convertedValue);
} else {
try {
list.set(index, convertedValue);
} catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
new StringBuilder().append("Invalid list index in property path '").append(propertyName)
.append("'").toString(),
ex);
}
}
//注入map类型的属性值
} else if (propValue instanceof Map) {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
Class mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(),
tokens.keys.length);
Class mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(pd.getReadMethod(),
tokens.keys.length);
Map map = (Map) propValue;
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
Object oldValue = null;
if (isExtractOldValueForEditor()) {
oldValue = map.get(convertedMapKey);
}
Object convertedMapValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), mapValueType,
TypeDescriptor.nested(property(pd), tokens.keys.length));
map.put(convertedMapKey, convertedMapValue);
} else {
throw new InvalidPropertyException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
new StringBuilder().append("Property referenced in indexed property path '")
.append(propertyName)
.append("' is neither an array nor a List nor a Map; returned value was [")
.append(pv.getValue()).append("]").toString());
}
} else {
//注入非集合类型属性
PropertyDescriptor pd = pv.resolvedDescriptor;
if ((pd == null) || (!(pd.getWriteMethod().getDeclaringClass().isInstance(this.object)))) {
pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
//如果无法获取到属性名或者属性没有提供setter(写方法)方法
if ((pd == null) || (pd.getWriteMethod() == null)) {
//如果属性值是可选的,即不是必须的,则忽略该属性值
if (pv.isOptional()) {
logger.debug(new StringBuilder().append("Ignoring optional value for property '")
.append(actualName).append("' - property not found on bean class [")
.append(getRootClass().getName()).append("]").toString());
return;
}
PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
//如果属性值是必须的,则抛出无法给属性赋值异常,因为没有提供setter方法
throw new NotWritablePropertyException(getRootClass(),
new StringBuilder().append(this.nestedPath).append(propertyName).toString(),
matches.buildErrorMessage(), matches.getPossibleMatches());
}
pv.getOriginalPropertyValue().resolvedDescriptor = pd;
}
Object oldValue = null;
try {
Object originalValue = pv.getValue();
Object valueToApply = originalValue;
//判断类型转换是否为必要
if (!(Boolean.FALSE.equals(pv.conversionNecessary))) {
//判断是否已经类型转换
if (pv.isConverted()) {
valueToApply = pv.getConvertedValue();
} else {
if ((isExtractOldValueForEditor()) && (pd.getReadMethod() != null)) {
//获取属性的getter方法(读方法),JDK内省机制
Method readMethod = pd.getReadMethod();
//如果属性的getter方法不是public访问控制权限的,即访问控制权限比较严格
//则使用JDK的反射机制强行访问非public的方法(暴力读取属性值)
if ((!(Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())))
&& (!(readMethod.isAccessible()))) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction(readMethod) {
public Object run() {
//匿名内部类,根据权限修改属性的读取控制限制
this.val$readMethod.setAccessible(true);
return null;
}
});
} else
readMethod.setAccessible(true);
}
try {
//属性没有提供getter方法时,调用潜在的读取属性值的方法,获取属性值
if (System.getSecurityManager() != null) {
oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction(readMethod) {
public Object run() throws Exception {
return this.val$readMethod.invoke(BeanWrapperImpl.this.object,
new Object[0]);
}
}, this.acc);
} else {
oldValue = readMethod.invoke(this.object, new Object[0]);
}
} catch (Exception ex) {
if (ex instanceof PrivilegedActionException) {
ex = ((PrivilegedActionException) ex).getException();
}
if (logger.isDebugEnabled()) {
logger.debug(new StringBuilder()
.append("Could not read previous value of property '")
.append(this.nestedPath).append(propertyName).append("'").toString(), ex);
}
}
}
//设置属性的注入值
valueToApply = convertForProperty(propertyName, oldValue, originalValue,
new TypeDescriptor(property(pd)));
}
//重新设置标记
pv.getOriginalPropertyValue().conversionNecessary = Boolean.valueOf(valueToApply != originalValue);
}
//通过内省调用属性Setter方法
Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor)
? ((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess()
: pd.getWriteMethod();
//如果属性的getter方法不是public访问控制权限的,即访问控制权限比较严格
//则使用JDK的反射机制强行访问非public的方法(暴力读取属性值)
if ((!(Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())))
&& (!(writeMethod.isAccessible()))) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction(writeMethod) {
public Object run() {
//强行设置可以访问
this.val$writeMethod.setAccessible(true);
return null;
}
});
} else {
//设置可以访问
writeMethod.setAccessible(true);
}
}
Object value = valueToApply;
if (System.getSecurityManager() != null) {
try {
//通过内省修改属性值
AccessController.doPrivileged(new PrivilegedExceptionAction(writeMethod, value) {
public Object run() throws Exception {
this.val$writeMethod.invoke(BeanWrapperImpl.this.object, new Object[]{this.val$value});
return null;
}
}, this.acc);
} catch (PrivilegedActionException ex) {
throw ex.getException();
}
} else
writeMethod.invoke(this.object, new Object[]{value});
} catch (TypeMismatchException ex) {
throw ex;
} catch (InvocationTargetException ex) {
PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this.rootObject,
new StringBuilder().append(this.nestedPath).append(propertyName).toString(), oldValue,
pv.getValue());
if (ex.getTargetException() instanceof ClassCastException) {
throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException());
}
throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
} catch (Exception ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.rootObject,
new StringBuilder().append(this.nestedPath).append(propertyName).toString(), oldValue,
pv.getValue());
throw new MethodInvocationException(pce, ex);
}
}
通过上述代码我们大概的知道Spring依赖注入的原理,即通过内省机制获取到beaninfo,然后通过setter和getter方法修改属性值。
最后我们回忆一下Spring依赖注入的过程:
当IOC容器调用getBean()的时候会触发依赖注入的过程,首先调用AbstractBeanFactory中doGetBean()方法判断Bean的种类,是单态的,则先在缓存中获取,否则创建bean,如果是原型的则每次都都创建一个新的bean,随后委托到子类AbstractAutowireCapableBeanFactory中的doCreateBean()去实例化Bean并进行属性的注入。
1.在实例化bean的时候使用BeanWrapper(接口)封装要实例化的bean,调用createBeanInstance()去实例化bean,这时会先检查这个Bean是否可以实例化如果配置了工厂方法实例化方式则优先使用工厂方法,然后判断是否开启自动装配,如果配置了使用构造器进行自动装配则使用构造器,如果没有使用其他策略。假如没有开启自动装配则默认使用bean的构造器实例化。instantiateBean()中则会委托到SimpleInstantiationStrategy判断究竟使用何种方式JDK代理实例bean还是使用CGLIB实例Bean,到此Bean完成实例化,并用BeanWrapperImpl封装。
2.Bean虽然已经完成实例化但是诸如Bean的引用对象等却还没有注入,随后调用populateBean,对bean的属性进行注入,在注入的时候需要先对需要进行注入的属性值进行解析,解析完成之后才能根据不同的装配策略完成注入,最后通过JDK内省机制完成注入。这也是为什么需要setter和getter方法才能完成注入的原因。