在上一篇(DI源码分析5)中,在AbstractAutowireCapableBeanFactory#populateBean中会设置bean的属性,其中在InstantiationAwareBeanPostProcessor#postProcessPropertyValues的地方会处理依赖的属性值
CommonAnnotationBeanPostProcessor处理标注了@Resource注解
//CommonAnnotationBeanPostProcessor#postProcessPropertyValues
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
//获取@Resource注解中配置的属性值元数据
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
//注入属性值
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
获取@Resource注解中配置的属性值元数据
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
//缓存
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
//先从容器缓存中查找
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//缓存中不存在
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//构建元数据,并放入缓存
metadata = buildResourceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
构建@Resource的元数据
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<>();
//处理标注注解的属性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//javax.xml.ws.WebServiceRef 注解
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
//属性是静态的 抛异常
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
}
//加入元素集合
currElements.add(new WebServiceRefElement(field, field, null));
}
//javax.ejb.EJB 注解
else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static fields");
}
currElements.add(new EjbRefElement(field, field, null));
}
//Resource 注解
else if (field.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static fields");
}
if (!ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
});
// 处理标注注解的方法 setter方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
}
else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new EjbRefElement(method, bridgedMethod, pd));
}
else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new ResourceElement(method, bridgedMethod, pd));
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}//循环处理父类
while (targetClass != null && targetClass != Object.class);
//构造注入元数据,并返回 元数据中包括类和属性
return new InjectionMetadata(clazz, elements);
}
注入元数据的构造方法
//org.springframework.beans.factory.annotation.InjectionMetadata#InjectionMetadata
public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
同上,AutowiredAnnotationBeanPostProcessor处理Autowired注解的属性,方法
//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//获取指定类中autowire相关注解的元信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//对Bean的属性进行自动注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
获取给定类的autowire相关注解元信息
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
//首先从容器中查找是否有给定类的autowire相关注解元信息
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
//解析给定类autowire相关注解元信息
metadata = buildAutowiringMetadata(clazz);
//将得到的给定类autowire相关注解元信息存储在容器缓存中
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
解析给定类autowire相关注解元信息
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
//处理属性
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//获取属性上的注解
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
//如果给定属性是静态的,则直接遍历下一个属性
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//判断注解的required属性值是否有效
boolean required = determineRequiredStatus(ann);
//加入元素集合
currElements.add(new AutowiredFieldElement(field, required));
}
});
//处理方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
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);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
//获取当前方法的属性描述符,即方法是可读的(readable)getter方法,还是可写的(writeable)setter方法
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);
}
获取给定对象的autowire相关注解
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
if (ao.getAnnotations().length > 0) {
//遍历所有相关的注解:@Autowire、@Value、javax.inject.Inject
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
//获取给定对象上的指定类型的注解
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
if (attributes != null) {
return attributes;
}
}
}
return null;
}
获取当前方法的属性描述符,即方法是可读的(readable)getter方法,还是可写的(writeable)setter方法
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
Assert.notNull(method, "Method must not be null");
PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
for (PropertyDescriptor pd : pds) {
if (method.equals(pd.getReadMethod()) || method.equals(pd.getWriteMethod())) {
return pd;
}
}
return null;
}
调用元数据的注入方法对属性,方法执行注入
//org.springframework.beans.factory.annotation.InjectionMetadata#inject
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
//这里数个循环,会对属性,方法进行注入
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}//注入在下一篇讲
element.inject(target, beanName, pvs);
}
}
}
对属性注入
//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//获取注入元素对象
Field field = (Field) this.member;
Object value;
//如果缓存中有
if (this.cached) {
//根据Bean名称解析缓存中的属性值
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
//如果当前对象没有被容器缓存
else {
//属性依赖描述符
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
//获取容器中的类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//根据容器中Bean定义,解析指定的依赖关系,获取依赖对象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
//如果当前对象没有被容器缓存
if (!this.cached) {
//获取到了当前对象的依赖对象,并且required属性为true
if (value != null || this.required) {
this.cachedFieldValue = desc;
//为指定Bean注册依赖Bean
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
//如果容器中有指定名称的Bean对象
if (beanFactory.containsBean(autowiredBeanName)) {
//依赖对象类型和属性类型匹配,默认按类型注入
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
//创建一个依赖对象的引用,同时缓存
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
//如果获取的依赖关系为null,且获取required属性为false
else {
//将属性值的缓存设置为null
this.cachedFieldValue = null;
}
//容器已经对当前属性的值缓存
this.cached = true;
}
}
}
//如果属性依赖值不为null
if (value != null) {
//反射,设置自动的访问控制权限为允许访问
ReflectionUtils.makeAccessible(field);
//反射,为Bean对象的属性设置值
field.set(bean, value);
}
}
}
对方法注入
//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//如果属性被显式设置为skip,则不进行注入
if (checkPropertySkipping(pvs)) {
return;
}
//获取注入元素
Method method = (Method) this.member;
Object[] arguments;
//如果有缓存
if (this.cached) {
//获取缓存中指定Bean名称的方法参数
arguments = resolveCachedArguments(beanName);
}
//没有缓存
else {
//获取方法的参数列表
Class<?>[] paramTypes = method.getParameterTypes();
//创建一个存放方法参数的数组
arguments = new Object[paramTypes.length];
//依赖描述符
DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length);
Assert.state(beanFactory != null, "No BeanFactory available");
//获取容器的类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
//创建方法参数对象
MethodParameter methodParam = new MethodParameter(method, i);
//解析方法的输入参数,为方法参数创建依赖描述符
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
descriptors[i] = currDesc;
try {
//根据容器中Bean定义解析依赖关系,获取方法参数依赖对象
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
synchronized (this) {
//如果当前方法没有被容器缓存
if (!this.cached) {
//如果方法的参数列表不为空
if (arguments != null) {
//为容器中缓存方法参数的对象赋值
Object[] cachedMethodArguments = new Object[paramTypes.length];
for (int i = 0; i < arguments.length; i++) {
cachedMethodArguments[i] = descriptors[i];
}
//为指定Bean注册依赖Bean
registerDependentBeans(beanName, autowiredBeans);
//依赖对象集合大小等于方法参数个数
if (autowiredBeans.size() == paramTypes.length) {
Iterator<String> it = autowiredBeans.iterator();
//为方法参数设置依赖对象
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
//容器中存在指定名称的Bean对象
if (beanFactory.containsBean(autowiredBeanName)) {
//参数类型和依赖对象类型匹配
if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
//创建一个依赖对象的引用,复制给方法相应的参
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
//如果方法参数列表为null,则设置容器对该方法参数的缓存为null
else {
this.cachedMethodArguments = null;
}
//设置容器已经对该方法缓存
this.cached = true;
}
}
}
//方法参数依赖对象不为null
if (arguments != null) {
try {
//反射,显式设置方法的访问控制权限为允许访问
ReflectionUtils.makeAccessible(method);
//反射调用Bean的方法
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex){
throw ex.getTargetException();
}
}
}