使用的spring版本:3.0.5
spring的IOC,通过配置的方式实现bean的初始化。
<bean/>的常用配置结构入下实例:
<bean id="mybatisTransactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="mybatisTransactionManager" />
<!-- 配置事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="query*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="select*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED,timeout_300,-Exception</prop>
</props>
</property>
</bean>
在以上的代码中,transactionManager及transactionAttributes两个配置属性的值是如何获取的呢?
对于spring的bean注入的源码分析推荐文章:
---逻辑较为完整的解析的注入的反射机制实现方式;
https://www.cnblogs.com/VergiLyn/p/6130188.html
---对bean注入实现的源码解析及入口做了详细的说明及源码拆解;
PS:感谢前人的成果。
在以上基础上,找到了
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean
此方法,此方法作为此次追寻的入口;
在逐步的debug中,找寻到了配置项中,bean的属性的初始化方法:
org.springframework.beans.GenericTypeAwarePropertyDescriptor.GenericTypeAwarePropertyDescriptor
package org.springframework.beans;
... ...
/**
* Extension of the standard JavaBeans PropertyDescriptor class,
* overriding <code>getPropertyType()</code> such that a generically
* declared type will be resolved against the containing bean class.
*
* @author Juergen Hoeller
* @since 2.5.2
*/
class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
public GenericTypeAwarePropertyDescriptor(Class beanClass, String propertyName,
Method readMethod, Method writeMethod, Class propertyEditorClass)
throws IntrospectionException {
super(propertyName, null, null);
this.beanClass = beanClass;
this.propertyEditorClass = propertyEditorClass;
Method readMethodToUse = BridgeMethodResolver.findBridgedMethod(readMethod);
Method writeMethodToUse = BridgeMethodResolver.findBridgedMethod(writeMethod);
if (writeMethodToUse == null && readMethodToUse != null) {
// Fallback: Original JavaBeans introspection might not have found matching setter
// method due to lack of bridge method resolution, in case of the getter using a
// covariant return type whereas the setter is defined for the concrete property type.
writeMethodToUse = ClassUtils.getMethodIfAvailable(this.beanClass,
"set" + StringUtils.capitalize(getName()), readMethodToUse.getReturnType());
}
this.readMethod = readMethodToUse;
this.writeMethod = writeMethodToUse;
if (this.writeMethod != null && this.readMethod == null) {
// Write method not matched against read method: potentially ambiguous through
// several overloaded variants, in which case an arbitrary winner has been chosen
// by the JDK's JavaBeans Introspector...
Set<Method> ambiguousCandidates = new HashSet<Method>();
for (Method method : beanClass.getMethods()) {
if (method.getName().equals(writeMethodToUse.getName()) &&
!method.equals(writeMethodToUse) && !method.isBridge()) {
ambiguousCandidates.add(method);
}
}
if (!ambiguousCandidates.isEmpty()) {
this.ambiguousWriteMethods = ambiguousCandidates;
}
}
}
}
从以上的实例代码中,可得出如下结论:
<bean>标签中property属性的name的值name_value确定逻辑为:在class属性的方法中,可找到"set"+name_value<首字母大写>的方法,即可进行配置。
以上事务的注入中
org.springframework.transaction.interceptor.TransactionInterceptor
此类可找到"setTransactionManager"和"setTransactionAttributes" 方法:
其父类:
org.springframework.transaction.interceptor.TransactionAspectSupport
有此二方法的实现。