什么是Spring呢?
我的理解是:Spring是一个容器。只不过这个容器设计的十分复制和巧妙。它外层是一个叫ApplicatContext的容器,内层存在一个叫BeanFactory的容器来管理bean的创建与管理。它向上可以连接视图层,展示页面,向下可以映射dao层操作数据。它通过Ioc和DI来管理程序的javaBean,实现MVC中的M和V的连接中介。
什么是Ioc/DI呢
Ioc/DI 就是 控制反转/依赖注入 。对象之间的关系交由Spring容器来管理。比如我们需要在A类中调用B类。以前的做法是在A类中直接 B b = new B()。
那么现在有了Spring之后这个过程就交由Spring管理。有Spring来管理什么时间创建B类,什么时间调用以及什么时间销毁。那么我们必须要创建这样一个容器吧,同时需要一种描述让容器知道我们程序的POJO类直接的关系,最直观的描述是通过配置文件来实现。
目前通用的主要是properties和xml等语义化配置文件。
描述对象关系的文件存放在哪里?
可能是 classpath , filesystem ,或者是 URL 网络资源, servletContext 等。
回到正题,有了配置文件,还需要对配置文件解析。
不同的配置文件对对象的描述不一样,如标准的,自定义声明式的,如何统一? 在内部需要有一个统一的关于对象的定义,所有外部的描述都必须转化成统一的描述定义。
如何对不同的配置文件进行解析?需要对不同的配置文件语法,采用不同的解析器
从上面可知:Ioc和DI肯定是spring中重要的模块。那么问题来了,它是如何被设计的呢?
一个POJO类,是如何被spring容器感知并自动纳入管理的呢?这个就需要从Spring如何感知POJO类开始。
一、Spring如何感知我们的POJO类
1、xml配置文件
Spring解析Xml配置需要用到dom4j。BeanDefinitionReader的设计用意是在启动Spring时加载BeanDefintion对象。Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构,每一个受管的对象,在容器中都会有一个BeanDefinition的实例与之相对应。该BeanDefinition的实例负责保存对象的所有必要信息,包括其对应的对象的class类型、是否是抽象类、构造方法参数以及其他属性。 BeanDefinition结构如下:
//元数据操作接口
public interface AttributeAccessor
{
//设置元数据
public abstract void setAttribute(String s, Object obj);
//获取元数据
public abstract Object getAttribute(String s);
//删除元数据
public abstract Object removeAttribute(String s);
// 是否含有元数据
public abstract boolean hasAttribute(String s);
//获取元数据的name数组
public abstract String[] attributeNames();
}
//用于承载bean对象
public interface BeanMetadataElement
{
//获取当前 元素的配置源bean对象
public abstract Object getSource();
}
//用于描述一个具体bean实例
public interface BeanDefinition
extends AttributeAccessor, BeanMetadataElement
{
//返回该bean定义的父bean定义的名称,如果有的话
public abstract String getParentName();
public abstract void setParentName(String s);
//获取bean对象的className
public abstract String getBeanClassName();
public abstract void setBeanClassName(String s);
//返回创建该bean对象的工厂类
public abstract String getFactoryBeanName();
public abstract void setFactoryBeanName(String s);
//返回创建该bean对象的工厂方法
public abstract String getFactoryMethodName();
public abstract void setFactoryMethodName(String s);
//返回该bean的初始化方式:单例或者多例方式 默认单例模式
public abstract boolean isLazyInit();
public abstract void setLazyInit(boolean flag);
//返回该bean的依赖对象
public abstract String[] getDependsOn();
public transient abstract void setDependsOn(String as[]);
//是否为被自动装配
public abstract boolean isAutowireCandidate();
public abstract void setAutowireCandidate(boolean flag);
//是否为主候选bean 使用注解 @Primary
public abstract boolean isPrimary();
public abstract void setPrimary(boolean flag);
//返回此bean的构造函数参数值
public abstract ConstructorArgumentValues getConstructorArgumentValues();
//返回该bean的普通属性集合
public abstract MutablePropertyValues getPropertyValues();
//判断该bean是否为单利
public abstract boolean isSingleton();
//判断该bean是否为多例
public abstract boolean isPrototype();
//判断该bean是否为抽象方法
public abstract boolean isAbstract();
//获得这个bean的应用
public abstract int getRole();
//返回对该bean的描述
public abstract String getDescription();
//返回该bean定义来自的资源的描述(用于在出现错误时显示上下文)
public abstract String getResourceDescription();
public abstract BeanDefinition getOriginatingBeanDefinition();
//单例
public static final String SCOPE_SINGLETON = "singleton";
//多例
public static final String SCOPE_PROTOTYPE = "prototype";
//bean角色 用户
public static final int ROLE_APPLICATION = 0;
//某些复杂的配置
public static final int ROLE_SUPPORT = 1;
//完全内部使用
public static final int ROLE_INFRASTRUCTURE = 2;
}
//抽象类 基础bean
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable
{
//空构造函数
protected AbstractBeanDefinition()
{
this(null, null);
}
//知道的构造函数的参数值和属性值
protected AbstractBeanDefinition(ConstructorArgumentValues cargs, MutablePropertyValues pvs)
{
scope = "";
abstractFlag = false;
lazyInit = false;
autowireMode = 0;
dependencyCheck = 0;
autowireCandidate = true;
primary = false;
qualifiers = new LinkedHashMap(0);
nonPublicAccessAllowed = true;
lenientConstructorResolution = true;
methodOverrides = new MethodOverrides();
enforceInitMethod = true;
enforceDestroyMethod = true;
synthetic = false;
role = 0;
setConstructorArgumentValues(cargs);
setPropertyValues(pvs);
}
//深拷贝构造
protected AbstractBeanDefinition(BeanDefinition original)
{
scope = "";
abstractFlag = false;
lazyInit = false;
autowireMode = 0;
dependencyCheck = 0;
autowireCandidate = true;
primary = false;
qualifiers = new LinkedHashMap(0);
nonPublicAccessAllowed = true;
lenientConstructorResolution = true;
methodOverrides = new MethodOverrides();
enforceInitMethod = true;
enforceDestroyMethod = true;
synthetic = false;
role = 0;
setParentName(original.getParentName());
setBeanClassName(original.getBeanClassName());
setFactoryBeanName(original.getFactoryBeanName());
setFactoryMethodName(original.getFactoryMethodName());
setScope(original.getScope());
setAbstract(original.isAbstract());
setLazyInit(original.isLazyInit());
setRole(original.getRole());
setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
setSource(original.getSource());
copyAttributesFrom(original);
if(original instanceof AbstractBeanDefinition)
{
AbstractBeanDefinition originalAbd = (AbstractBeanDefinition)original;
if(originalAbd.hasBeanClass())
setBeanClass(originalAbd.getBeanClass());
setAutowireMode(originalAbd.getAutowireMode());
setDependencyCheck(originalAbd.getDependencyCheck());
setDependsOn(originalAbd.getDependsOn());
setAutowireCandidate(originalAbd.isAutowireCandidate());
copyQualifiersFrom(originalAbd);
setPrimary(originalAbd.isPrimary());
setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
setInitMethodName(originalAbd.getInitMethodName());
setEnforceInitMethod(originalAbd.isEnforceInitMethod());
setDestroyMethodName(originalAbd.getDestroyMethodName());
setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
setSynthetic(originalAbd.isSynthetic());
setResource(originalAbd.getResource());
} else
{
setResourceDescription(original.getResourceDescription());
}
}
// 从给定的bean定义(大概是子)中覆盖此bean定义(可能是来自父子继承关系的复制父)的设置。
public void overrideFrom(BeanDefinition other)
{
if(StringUtils.hasLength(other.getBeanClassName()))
setBeanClassName(other.getBeanClassName());
if(StringUtils.hasLength(other.getFactoryBeanName()))
setFactoryBeanName(other.getFactoryBeanName());
if(StringUtils.hasLength(other.getFactoryMethodName()))
setFactoryMethodName(other.getFactoryMethodName());
if(StringUtils.hasLength(other.getScope()))
setScope(other.getScope());
setAbstract(other.isAbstract());
setLazyInit(other.isLazyInit());
setRole(other.getRole());
//更新存在的,新增未拥有的
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
getPropertyValues().addPropertyValues(other.getPropertyValues());
setSource(other.getSource());
copyAttributesFrom(other);
//更新AbstractBeanDefinition中特有的属性
if(other instanceof AbstractBeanDefinition)
{
AbstractBeanDefinition otherAbd = (AbstractBeanDefinition)other;
if(otherAbd.hasBeanClass())
setBeanClass(otherAbd.getBeanClass());
setAutowireCandidate(otherAbd.isAutowireCandidate());
setAutowireMode(otherAbd.getAutowireMode());
copyQualifiersFrom(otherAbd);
setPrimary(otherAbd.isPrimary());
setDependencyCheck(otherAbd.getDependencyCheck());
setDependsOn(otherAbd.getDependsOn());
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
if(StringUtils.hasLength(otherAbd.getInitMethodName()))
{
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if(otherAbd.getDestroyMethodName() != null)
{
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
setSynthetic(otherAbd.isSynthetic());
setResource(otherAbd.getResource());
} else
{
//更新资源描述
setResourceDescription(other.getResourceDescription());
}
}
//将所提供的默认值应用于此bean。
public void applyDefaults(BeanDefinitionDefaults defaults)
{
setLazyInit(defaults.isLazyInit());
setAutowireMode(defaults.getAutowireMode());
setDependencyCheck(defaults.getDependencyCheck());
setInitMethodName(defaults.getInitMethodName());
setEnforceInitMethod(false);
setDestroyMethodName(defaults.getDestroyMethodName());
setEnforceDestroyMethod(false);
}
//操作beanclass对象
//是否已经设置
public boolean hasBeanClass()
{
return beanClass instanceof Class;
}
//设置class对象
public void setBeanClass(Class beanClass)
{
this.beanClass = beanClass;
}
//若已经解析就返回这个包装类。
public Class getBeanClass()
throws IllegalStateException
{
Object beanClassObject = beanClass;
if(beanClassObject == null)
throw new IllegalStateException("No bean class specified on bean definition");
if(!(beanClassObject instanceof Class))
throw new IllegalStateException((new StringBuilder()).append("Bean class name [").append(beanClassObject).append("] has not been resolved into an actual Class").toString());
else
return (Class)beanClassObject;
}
//设置className
public void setBeanClassName(String beanClassName)
{
beanClass = beanClassName;
}
//获取设置className
public String getBeanClassName()
{
Object beanClassObject = beanClass;
if(beanClassObject instanceof Class)
return ((Class)beanClassObject).getName();
else
return (String)beanClassObject;
}
//解析类
public Class resolveBeanClass(ClassLoader classLoader)
throws ClassNotFoundException
{
String className = getBeanClassName();
if(className == null)
{
return null;
} else
{
Class resolvedClass = ClassUtils.forName(className, classLoader);
beanClass = resolvedClass;
return resolvedClass;
}
}
//scope操作
public void setScope(String scope)
{
this.scope = scope;
}
public String getScope()
{
return scope;
}
public boolean isSingleton()
{
return "singleton".equals(scope) || "".equals(scope);
}
public boolean isPrototype()
{
return "prototype".equals(scope);
}
public void setAbstract(boolean abstractFlag)
{
this.abstractFlag = abstractFlag;
}
public boolean isAbstract()
{
return abstractFlag;
}
public void setLazyInit(boolean lazyInit)
{
this.lazyInit = lazyInit;
}
public boolean isLazyInit()
{
return lazyInit;
}
public void setAutowireMode(int autowireMode)
{
this.autowireMode = autowireMode;
}
public int getAutowireMode()
{
return autowireMode;
}
/**
* Return the resolved autowire code,
* (resolving AUTOWIRE_AUTODETECT to AUTOWIRE_CONSTRUCTOR or AUTOWIRE_BY_TYPE).
* @see #AUTOWIRE_AUTODETECT
* @see #AUTOWIRE_CONSTRUCTOR
* @see #AUTOWIRE_BY_TYPE
*/
public int getResolvedAutowireMode()
{
if(autowireMode == 4)
{
Constructor constructors[] = getBeanClass().getConstructors();
Constructor aconstructor[] = constructors;
int i = aconstructor.length;
for(int j = 0; j < i; j++)
{
Constructor constructor = aconstructor[j];
if(constructor.getParameterTypes().length == 0)
return 2;
}
return 3;
} else
{
return autowireMode;
}
}
//设置依赖检查
public void setDependencyCheck(int dependencyCheck)
{
this.dependencyCheck = dependencyCheck;
}
public int getDependencyCheck()
{
return dependencyCheck;
}
//设置依赖
public transient void setDependsOn(String dependsOn[])
{
this.dependsOn = dependsOn;
}
public String[] getDependsOn()
{
return dependsOn;
}
//设置是否做为其他bean自动装配的候选者
public void setAutowireCandidate(boolean autowireCandidate)
{
this.autowireCandidate = autowireCandidate;
}
public boolean isAutowireCandidate()
{
return autowireCandidate;
}
public void setPrimary(boolean primary)
{
this.primary = primary;
}
public boolean isPrimary()
{
return primary;
}
public void addQualifier(AutowireCandidateQualifier qualifier)
{
qualifiers.put(qualifier.getTypeName(), qualifier);
}
public boolean hasQualifier(String typeName)
{
return qualifiers.keySet().contains(typeName);
}
public AutowireCandidateQualifier getQualifier(String typeName)
{
return (AutowireCandidateQualifier)qualifiers.get(typeName);
}
public Set getQualifiers()
{
return new LinkedHashSet(qualifiers.values());
}
public void copyQualifiersFrom(AbstractBeanDefinition source)
{
Assert.notNull(source, "Source must not be null");
qualifiers.putAll(source.qualifiers);
}
public void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed)
{
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
}
public boolean isNonPublicAccessAllowed()
{
return nonPublicAccessAllowed;
}
public void setLenientConstructorResolution(boolean lenientConstructorResolution)
{
this.lenientConstructorResolution = lenientConstructorResolution;
}
public boolean isLenientConstructorResolution()
{
return lenientConstructorResolution;
}
public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues)
{
this.constructorArgumentValues = constructorArgumentValues == null ? new ConstructorArgumentValues() : constructorArgumentValues;
}
public ConstructorArgumentValues getConstructorArgumentValues()
{
return constructorArgumentValues;
}
public boolean hasConstructorArgumentValues()
{
return !constructorArgumentValues.isEmpty();
}
public void setPropertyValues(MutablePropertyValues propertyValues)
{
this.propertyValues = propertyValues == null ? new MutablePropertyValues() : propertyValues;
}
public MutablePropertyValues getPropertyValues()
{
return propertyValues;
}
public void setMethodOverrides(MethodOverrides methodOverrides)
{
this.methodOverrides = methodOverrides == null ? new MethodOverrides() : methodOverrides;
}
public MethodOverrides getMethodOverrides()
{
return methodOverrides;
}
public void setFactoryBeanName(String factoryBeanName)
{
this.factoryBeanName = factoryBeanName;
}
public String getFactoryBeanName()
{
return factoryBeanName;
}
public void setFactoryMethodName(String factoryMethodName)
{
this.factoryMethodName = factoryMethodName;
}
public String getFactoryMethodName()
{
return factoryMethodName;
}
public void setInitMethodName(String initMethodName)
{
this.initMethodName = initMethodName;
}
public String getInitMethodName()
{
return initMethodName;
}
public void setEnforceInitMethod(boolean enforceInitMethod)
{
this.enforceInitMethod = enforceInitMethod;
}
public boolean isEnforceInitMethod()
{
return enforceInitMethod;
}
public void setDestroyMethodName(String destroyMethodName)
{
this.destroyMethodName = destroyMethodName;
}
public String getDestroyMethodName()
{
return destroyMethodName;
}
public void setEnforceDestroyMethod(boolean enforceDestroyMethod)
{
this.enforceDestroyMethod = enforceDestroyMethod;
}
public boolean isEnforceDestroyMethod()
{
return enforceDestroyMethod;
}
public void setSynthetic(boolean synthetic)
{
this.synthetic = synthetic;
}
public boolean isSynthetic()
{
return synthetic;
}
public void setRole(int role)
{
this.role = role;
}
public int getRole()
{
return role;
}
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
public void setResource(Resource resource)
{
this.resource = resource;
}
public Resource getResource()
{
return resource;
}
public void setResourceDescription(String resourceDescription)
{
resource = new DescriptiveResource(resourceDescription);
}
public String getResourceDescription()
{
return resource == null ? null : resource.getDescription();
}
public void setOriginatingBeanDefinition(BeanDefinition originatingBd)
{
resource = new BeanDefinitionResource(originatingBd);
}
public BeanDefinition getOriginatingBeanDefinition()
{
return (resource instanceof BeanDefinitionResource) ? ((BeanDefinitionResource)resource).getBeanDefinition() : null;
}
public void validate()
throws BeanDefinitionValidationException
{
if(!getMethodOverrides().isEmpty() && getFactoryMethodName() != null)
throw new BeanDefinitionValidationException("Cannot combine static factory method with method overrides: the static factory method must create the instance");
if(hasBeanClass())
prepareMethodOverrides();
}
public void prepareMethodOverrides()
throws BeanDefinitionValidationException
{
MethodOverrides methodOverrides = getMethodOverrides();
if(!methodOverrides.isEmpty())
{
MethodOverride mo;
for(Iterator iterator = methodOverrides.getOverrides().iterator(); iterator.hasNext(); prepareMethodOverride(mo))
mo = (MethodOverride)iterator.next();
}
}
protected void prepareMethodOverride(MethodOverride mo)
throws BeanDefinitionValidationException
{
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if(count == 0)
throw new BeanDefinitionValidationException((new StringBuilder()).append("Invalid method override: no method with name '").append(mo.getMethodName()).append("' on class [").append(getBeanClassName()).append("]").toString());
if(count == 1)
mo.setOverloaded(false);
}
public Object clone()
{
return cloneBeanDefinition();
}
public abstract AbstractBeanDefinition cloneBeanDefinition();
public boolean equals(Object other)
{
if(this == other)
return true;
if(!(other instanceof AbstractBeanDefinition))
return false;
AbstractBeanDefinition that = (AbstractBeanDefinition)other;
if(!ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName()))
return false;
if(!ObjectUtils.nullSafeEquals(scope, that.scope))
return false;
if(abstractFlag != that.abstractFlag)
return false;
if(lazyInit != that.lazyInit)
return false;
if(autowireMode != that.autowireMode)
return false;
if(dependencyCheck != that.dependencyCheck)
return false;
if(!Arrays.equals(dependsOn, that.dependsOn))
return false;
if(autowireCandidate != that.autowireCandidate)
return false;
if(!ObjectUtils.nullSafeEquals(qualifiers, that.qualifiers))
return false;
if(primary != that.primary)
return false;
if(nonPublicAccessAllowed != that.nonPublicAccessAllowed)
return false;
if(lenientConstructorResolution != that.lenientConstructorResolution)
return false;
if(!ObjectUtils.nullSafeEquals(constructorArgumentValues, that.constructorArgumentValues))
return false;
if(!ObjectUtils.nullSafeEquals(propertyValues, that.propertyValues))
return false;
if(!ObjectUtils.nullSafeEquals(methodOverrides, that.methodOverrides))
return false;
if(!ObjectUtils.nullSafeEquals(factoryBeanName, that.factoryBeanName))
return false;
if(!ObjectUtils.nullSafeEquals(factoryMethodName, that.factoryMethodName))
return false;
if(!ObjectUtils.nullSafeEquals(initMethodName, that.initMethodName))
return false;
if(enforceInitMethod != that.enforceInitMethod)
return false;
if(!ObjectUtils.nullSafeEquals(destroyMethodName, that.destroyMethodName))
return false;
if(enforceDestroyMethod != that.enforceDestroyMethod)
return false;
if(synthetic != that.synthetic)
return false;
if(role != that.role)
return false;
else
return super.equals(other);
}
public int hashCode()
{
int hashCode = ObjectUtils.nullSafeHashCode(getBeanClassName());
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(scope);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(constructorArgumentValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(propertyValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(factoryBeanName);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(factoryMethodName);
hashCode = 29 * hashCode + super.hashCode();
return hashCode;
}
public String toString()
{
StringBuilder sb = new StringBuilder("class [");
sb.append(getBeanClassName()).append("]");
sb.append("; scope=").append(scope);
sb.append("; abstract=").append(abstractFlag);
sb.append("; lazyInit=").append(lazyInit);
sb.append("; autowireMode=").append(autowireMode);
sb.append("; dependencyCheck=").append(dependencyCheck);
sb.append("; autowireCandidate=").append(autowireCandidate);
sb.append("; primary=").append(primary);
sb.append("; factoryBeanName=").append(factoryBeanName);
sb.append("; factoryMethodName=").append(factoryMethodName);
sb.append("; initMethodName=").append(initMethodName);
sb.append("; destroyMethodName=").append(destroyMethodName);
if(resource != null)
sb.append("; defined in ").append(resource.getDescription());
return sb.toString();
}
public static final String SCOPE_DEFAULT = "";
public static final int AUTOWIRE_NO = 0;
public static final int AUTOWIRE_BY_NAME = 1;
public static final int AUTOWIRE_BY_TYPE = 2;
public static final int AUTOWIRE_CONSTRUCTOR = 3;
/**
* @deprecated Field AUTOWIRE_AUTODETECT is deprecated
*/
public static final int AUTOWIRE_AUTODETECT = 4;
public static final int DEPENDENCY_CHECK_NONE = 0;
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
public static final int DEPENDENCY_CHECK_ALL = 3;
public static final String INFER_METHOD = "(inferred)";
private volatile Object beanClass;
private String scope;
private boolean abstractFlag;
private boolean lazyInit;
private int autowireMode;
private int dependencyCheck;
private String dependsOn[];
private boolean autowireCandidate;
private boolean primary;
private final Map qualifiers;
private boolean nonPublicAccessAllowed;
private boolean lenientConstructorResolution;
private ConstructorArgumentValues constructorArgumentValues;
private MutablePropertyValues propertyValues;
private MethodOverrides methodOverrides;
private String factoryBeanName;
private String factoryMethodName;
private String initMethodName;
private String destroyMethodName;
private boolean enforceInitMethod;
private boolean enforceDestroyMethod;
private boolean synthetic;
private int role;
private String description;
private Resource resource;
}
在配置文件中可以定义父和子,父用RootBeanDefinition表示,而子用ChildBeanDefiniton表示,而没有父的就使用RootBeanDefinition表示
public class ChildBeanDefinition extends AbstractBeanDefinition
{
//构造函数
public ChildBeanDefinition(String parentName)
{
this.parentName = parentName;
}
public ChildBeanDefinition(String parentName, MutablePropertyValues pvs)
{
super(null, pvs);
this.parentName = parentName;
}
public ChildBeanDefinition(String parentName, ConstructorArgumentValues cargs, MutablePropertyValues pvs)
{
super(cargs, pvs);
this.parentName = parentName;
}
public ChildBeanDefinition(String parentName, Class beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs)
{
super(cargs, pvs);
this.parentName = parentName;
setBeanClass(beanClass);
}
public ChildBeanDefinition(String parentName, String beanClassName, ConstructorArgumentValues cargs, MutablePropertyValues pvs)
{
super(cargs, pvs);
this.parentName = parentName;
setBeanClassName(beanClassName);
}
public ChildBeanDefinition(ChildBeanDefinition original)
{
super(original);
}
//设置父bean名称
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public String getParentName()
{
return parentName;
}
//验证当前bean定义
public void validate()
throws BeanDefinitionValidationException
{
super.validate();
if(parentName == null)
throw new BeanDefinitionValidationException("'parentName' must be set in ChildBeanDefinition");
else
return;
}
//深度拷贝bean定义
public AbstractBeanDefinition cloneBeanDefinition()
{
return new ChildBeanDefinition(this);
}
public boolean equals(Object other)
{
if(this == other)
return true;
if(!(other instanceof ChildBeanDefinition))
{
return false;
} else
{
ChildBeanDefinition that = (ChildBeanDefinition)other;
return ObjectUtils.nullSafeEquals(parentName, that.parentName) && super.equals(other);
}
}
public int hashCode()
{
return ObjectUtils.nullSafeHashCode(parentName) * 29 + super.hashCode();
}
public String toString()
{
StringBuilder sb = new StringBuilder("Child bean with parent '");
sb.append(parentName).append("': ").append(super.toString());
return sb.toString();
}
private String parentName;
}
GenericBeanDefinition是自2.5以后新加入的bean文件配置属性定义类,是一站式服务类,用于替代ChildBeanDefinition类
//
public class GenericBeanDefinition extends AbstractBeanDefinition
{
//空构造方法
public GenericBeanDefinition()
{
}
//构造方法
public GenericBeanDefinition(BeanDefinition original)
{
super(original);
}
/设置父bean名称
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public String getParentName()
{
return parentName;
}
//深度拷贝自身
public AbstractBeanDefinition cloneBeanDefinition()
{
return new GenericBeanDefinition(this);
}
public boolean equals(Object other)
{
return this == other || (other instanceof GenericBeanDefinition) && super.equals(other);
}
public String toString()
{
StringBuilder sb = new StringBuilder("Generic bean");
if(parentName != null)
sb.append(" with parent '").append(parentName).append("'");
sb.append(": ").append(super.toString());
return sb.toString();
}
private String parentName;
}
public class RootBeanDefinition extends AbstractBeanDefinition
{
public RootBeanDefinition()
{
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
}
public RootBeanDefinition(Class beanClass)
{
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
setBeanClass(beanClass);
}
public RootBeanDefinition(Class beanClass, int autowireMode, boolean dependencyCheck)
{
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
setBeanClass(beanClass);
setAutowireMode(autowireMode);
if(dependencyCheck && getResolvedAutowireMode() != 3)
setDependencyCheck(1);
}
public RootBeanDefinition(Class beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs)
{
super(cargs, pvs);
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
setBeanClass(beanClass);
}
public RootBeanDefinition(String beanClassName)
{
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
setBeanClassName(beanClassName);
}
public RootBeanDefinition(String beanClassName, ConstructorArgumentValues cargs, MutablePropertyValues pvs)
{
super(cargs, pvs);
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
setBeanClassName(beanClassName);
}
public RootBeanDefinition(RootBeanDefinition original)
{
super(original);
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
allowCaching = original.allowCaching;
decoratedDefinition = original.decoratedDefinition;
targetType = original.targetType;
isFactoryMethodUnique = original.isFactoryMethodUnique;
}
RootBeanDefinition(BeanDefinition original)
{
super(original);
allowCaching = true;
isFactoryMethodUnique = false;
constructorArgumentLock = new Object();
constructorArgumentsResolved = false;
postProcessingLock = new Object();
postProcessed = false;
}
public String getParentName()
{
return null;
}
public void setParentName(String parentName)
{
if(parentName != null)
throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
else
return;
}
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition)
{
this.decoratedDefinition = decoratedDefinition;
}
public BeanDefinitionHolder getDecoratedDefinition()
{
return decoratedDefinition;
}
public void setTargetType(Class targetType)
{
this.targetType = targetType;
}
public Class getTargetType()
{
return targetType;
}
public void setUniqueFactoryMethodName(String name)
{
Assert.hasText(name, "Factory method name must not be empty");
setFactoryMethodName(name);
isFactoryMethodUnique = true;
}
public boolean isFactoryMethod(Method candidate)
{
return candidate != null && candidate.getName().equals(getFactoryMethodName());
}
public Method getResolvedFactoryMethod()
{
Object obj = constructorArgumentLock;
JVM INSTR monitorenter ;
Object candidate = resolvedConstructorOrFactoryMethod;
return (candidate instanceof Method) ? (Method)candidate : null;
Exception exception;
exception;
throw exception;
}
public void registerExternallyManagedConfigMember(Member configMember)
{
synchronized(postProcessingLock)
{
if(externallyManagedConfigMembers == null)
externallyManagedConfigMembers = new HashSet(1);
externallyManagedConfigMembers.add(configMember);
}
}
public boolean isExternallyManagedConfigMember(Member configMember)
{
Object obj = postProcessingLock;
JVM INSTR monitorenter ;
return externallyManagedConfigMembers != null && externallyManagedConfigMembers.contains(configMember);
Exception exception;
exception;
throw exception;
}
public void registerExternallyManagedInitMethod(String initMethod)
{
synchronized(postProcessingLock)
{
if(externallyManagedInitMethods == null)
externallyManagedInitMethods = new HashSet(1);
externallyManagedInitMethods.add(initMethod);
}
}
public boolean isExternallyManagedInitMethod(String initMethod)
{
Object obj = postProcessingLock;
JVM INSTR monitorenter ;
return externallyManagedInitMethods != null && externallyManagedInitMethods.contains(initMethod);
Exception exception;
exception;
throw exception;
}
public void registerExternallyManagedDestroyMethod(String destroyMethod)
{
synchronized(postProcessingLock)
{
if(externallyManagedDestroyMethods == null)
externallyManagedDestroyMethods = new HashSet(1);
externallyManagedDestroyMethods.add(destroyMethod);
}
}
public boolean isExternallyManagedDestroyMethod(String destroyMethod)
{
Object obj = postProcessingLock;
JVM INSTR monitorenter ;
return externallyManagedDestroyMethods != null && externallyManagedDestroyMethods.contains(destroyMethod);
Exception exception;
exception;
throw exception;
}
public RootBeanDefinition cloneBeanDefinition()
{
return new RootBeanDefinition(this);
}
public boolean equals(Object other)
{
return this == other || (other instanceof RootBeanDefinition) && super.equals(other);
}
public String toString()
{
return (new StringBuilder()).append("Root bean: ").append(super.toString()).toString();
}
public volatile AbstractBeanDefinition cloneBeanDefinition()
{
return cloneBeanDefinition();
}
//是否使用缓存 默认使用
boolean allowCaching;
//bean定义的持有者(修饰bean定义)
private BeanDefinitionHolder decoratedDefinition;
// bean指定的目标类型定义
private volatile Class targetType;
//是否已经指定引用非重载方法的工厂方法名。
boolean isFactoryMethodUnique;
//用于构造函数注入属性的锁对象
final Object constructorArgumentLock;
//缓存已解析的构造函数或工厂方法
Object resolvedConstructorOrFactoryMethod;
/将构造函数参数标记为已解析
volatile Class resolvedFactoryMethodReturnType;
//缓存完全解析的构造函数参数
boolean constructorArgumentsResolved;
//缓存完全解析的构造函数参数
Object resolvedConstructorArguments[];
//缓存部分准备好的构造函数参数
Object preparedConstructorArguments[];
//后处理锁对象
final Object postProcessingLock;
/表明已应用mergedbeandefinitionpostprocessor
boolean postProcessed;
//指示已启动的一个实例化之前的后置处理器。
volatile Boolean beforeInstantiationResolved;
private Set externallyManagedConfigMembers;
private Set externallyManagedInitMethods;
private Set externallyManagedDestroyMethods;
}
//接口:支持注释元数据的bean定义
public interface AnnotatedBeanDefinition extends BeanDefinition {
//获取此bean定义bean类的注释元数据(以及基本类元数据)。
AnnotationMetadata getMetadata();
}
//实现类一:支持注释元数据的普通bean定义
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
//当前bean的注解元数据
private final AnnotationMetadata metadata;
//通过给定beanClass 构造对象
public AnnotatedGenericBeanDefinition(Class> beanClass) {
setBeanClass(beanClass);
this.metadata = new StandardAnnotationMetadata(beanClass, true);
}
//给定注解元数据,构造对象
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata) {
setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
else {
setBeanClassName(metadata.getClassName());
}
this.metadata = metadata;
}
//获取bean的注解元数据
public final AnnotationMetadata getMetadata() {
return this.metadata;
}
}
//实现类二:支持注释元数据bean定义
//通过 Annotation 配置方式定义的 Bean 属性经 Spring 框架解析后会封装成 ScannedGenericBeanDefinition
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
//当前bean的注解元数据
private final AnnotationMetadata metadata;
//metadatareader:扫描指定类的注释元数据
public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
Assert.notNull(metadataReader, "MetadataReader must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
setBeanClassName(this.metadata.getClassName());
}
//获取bean的注解元数据
public final AnnotationMetadata getMetadata() {
return this.metadata;
}
}
通过BeanDefinition 类Spring已经把bean的所有信息存到到容器中。然后利用BeanDefinitionReader来读取。由于是用xml配置的,所以这里主要使用XmlBeanDefinitionReader来读取BeanDefinition对象。
/**
* 从单个指定的资源对象中加载BeanDefintion,并返回加载的BeanDefintion个数
*/
int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
/**
* 从多个指定的资源对象中加载BeanDefintion,并返回加载的BeanDefintion个数
*/
int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
/**
* 从单个指定的资源地址中加载BeanDefintion,并返回加载的BeanDefintion个数。
* 如果资源加载器是ResourcePatternResolver对象,那么location参数可以使用通配符。
*/
int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;
/**
* 从多个指定的资源地址中加载BeanDefintion,并返回加载的BeanDefintion个数。
*/
int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
在spring中直接使用XmlBeanDefinitionReader的容器有XmlWebApplicationContext、ClassPathXmlApplicationContext、FileSystemXmlApplicationContext。下面就从XmlWebApplicationContext为例来探索xml配置的解析过程。
XmlWebApplicationContext解析配置文件分为以下2个过程:
1) 创建并初始化XmlBeanDefinitionReader 对象。
2)使用XmlBeanDefinitionReader 对象提供的接口方法来加载BeanDefinition对象。
下面我们通过spring源码来探讨这个2个过程。
XmlWebApplicationContext在创建完BeanFacotry的时候会调用它的loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法来加载BeanDefinition,loadBeanDefinitions方法的代码如下。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException
{ //根据给定的bean工厂创建新的XmlBeanDefinitionReader对象
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//使XmlBeanDefinitionReader对象与上下文对象在同一个资源环境中
beanDefinitionReader.setEnvironment(getEnvironment());
//使用上下文对象为XmlBeanDefinitionReader对象的资源加载器
beanDefinitionReader.setResourceLoader(this);
//设置EntityResolver对象,用于加载XML的xsd或者dtd文件
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//初始化XmlBeanDefitionReader
initBeanDefinitionReader(beanDefinitionReader);
//使用BeanDefinitionReader加载所有的BeanDefinition对象,见下面的代码
loadBeanDefinitions(beanDefinitionReader);
}
这段代码是为使用BeanDefinitionReader对象加载BeanDefinitioin对象做准备工作。BeanDefinitionRegistry对象是BeanDefinition对象的注册表,并且它是XmlBeanDefinitionReader对象创建时必须提供的,除此之外,其它的都使用默认或者由使用者提供。在XmlWebApplicationContext容器里,容器向BeanDefinitionReader提供了3个对象,第一个是资源环境Environment对象,它可用于判断beans标签的profile属性,后面会谈到;第二个是资源加载器ResourceLoader对象;最后一个是用于加载XML验证文件(dtd或者xsd文件)的EntityResolver对象。如果这些还不够,则可以扩展XmlWebApplicationContext容器,并重写initBeanDefinitionReader方法对BeanDefinitionReader做更多的初始化。
上图只是大致描述了XmlBeanDefinitionReader对象加载BeanDefinition的过程,还有些重点的旁枝末节没有展现出来,但这并不影响我们了解XmlBeanDefinitionReader解析xml配置的过程。下面我们看看XmlWebApplicationContext如何使用XmlBeanDefinitionReader对象,以及XmlBeanDefinitionReader对象如何按照这个流程执行的。
创建完成BeanDefinitionReader对象后,XmlWebApplicationContext调用它的loadBeanDefinitions(XmlBeanDefinitionReader reader)方法来使用BeanDefinitionReader对象。下面是loadBeanDefinitions(XmlBeanDefinitionReader reader)方法的代码。