1、首先从简单使用开始, 演示几种bean的创建情况
数据准备:
定义两个bean类:
public class Person {
private String name;
private Integer age;
private String email;
// ...getXXX() setXXX()(略)
}
public class Student {
private String grade;
private String clazz;
private Person person;
public Student() {
System.out.println("Student()");
}
public Student(String grade) {
System.out.println("Student(String grade)");
this.grade = grade;
}
public Student(String grade, String clazz) {
System.out.println("Student(String grade, String clazz)");
this.grade = grade;
this.clazz = clazz;
}
public Student(String grade, String clazz, Person person) {
System.out.println("Student(String grade, String clazz, Person person)");
this.grade = grade;
this.clazz = clazz;
this.person = person;
}
// ...getXXX() setXXX()(略)
}
spring xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="org.spring.xml.bean.Person">
<property name="name" value="lisi"></property>
<property name="age" value="12"></property>
<property name="email" value="lisi@123.com"></property>
</bean>
<bean id="student0" class="org.spring.xml.bean.Student">
<property name="grade" value="1年级"/>
<property name="clazz" value="2班"/>
</bean>
<bean id="student1" class="org.spring.xml.bean.Student">
<constructor-arg name="grade" value="1年级"/>
</bean>
<bean id="student2" class="org.spring.xml.bean.Student">
<constructor-arg name="grade" value="1年级"/>
<constructor-arg name="clazz" value="2班"/>
</bean>
<bean id="student3" class="org.spring.xml.bean.Student">
<constructor-arg name="grade" value="1年级"/>
<constructor-arg name="clazz" value="2班"/>
<constructor-arg name="person" ref="person"/>
</bean>
<bean id="student4" class="org.spring.xml.bean.Student" autowire="constructor">
<constructor-arg name="grade" value="1年级"/>
<constructor-arg name="clazz" value="2班"/>
</bean>
<bean id="student5" class="org.spring.xml.bean.Student" scope="prototype">
<constructor-arg name="grade" value="1年级"/>
<constructor-arg name="clazz" value="2班"/>
<constructor-arg name="person" ref="person"/>
</bean>
</beans>
测试代码:
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
ClassPathResource resource = new ClassPathResource("spring-config.xml");
reader.loadBeanDefinitions(resource);
Student student = beanFactory.getBean("student0", Student.class);
System.out.println("student0==>" + student);
System.out.println();
student = beanFactory.getBean("student1", Student.class);
System.out.println("student1==>" + student);
System.out.println();
student = beanFactory.getBean("student2", Student.class);
System.out.println("student2==>" + student);
System.out.println();
student = beanFactory.getBean("student3", Student.class);
System.out.println("student3==>" + student);
System.out.println();
student = beanFactory.getBean("student4", Student.class);
System.out.println("student4==>" + student);
System.out.println();
student = beanFactory.getBean("student5", Student.class);
System.out.println("student5==>" + student);
System.out.println();
student = beanFactory.getBean("student5", Student.class, new Object[]{"2年级", "4班"});
System.out.println("student5=传入2个参数=>" + student);
System.out.println();
student = beanFactory.getBean("student5", Student.class, new Object[]{"2年级", "4班", beanFactory.getBean(Person.class)});
System.out.println("student5=传入3个参数=>" + student);
System.out.println();
}
执行结果:
注意观察上面配置的差异和测试代码获取bean实例的差异,读懂源码的前提需要会灵活应用
========================接下来从源码分析调用逻辑========================
创建bean入口:AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, Object[] args)
package org;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
//最终bean的实例化是通过CglibSubclassingInstantiationStrategy来完成的
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
//分析流程 节点1
//bean工厂创建bean实例时都要进入该方法,Spring IOC的核心方法
@Override
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
//将AbstractBeanDefinition中的beanClass字段值由String转为Class类型
//Object beanClass = "XXX.XXX.BeanName" ==> Object beanClass = Class.forName("XXX.XXX.BeanName")
resolveBeanClass(mbd, beanName);
try {
/*
==================lookup-method====================
java代码
--------------------------------------------------
public class User {
public void say() {
System.out.println("I am User!!");
}
}
public class Student extends User {
@Override
public void say() {
System.out.println("I am student!!");
}
}
public abstract class LookUpBean {
public abstract User getUser();
}
---------------------------------------------------
xml配置
<bean id="user" class="org.spring.lookup.User"/>
<bean id="student" class="org.spring.lookup.Student"/>
<bean id="lookUpBean" class="org.spring.lookup.LookUpBean">
<lookup-method name="getUser" bean="student"></lookup-method>
</bean>
==================lookup-method==================================
====================replaced-method==============================
java代码
-----------------------------------------------------------------
public class ReplacedMethod implements MethodReplacer {
@Override
public Object reimplement(Object obj, Method method, Object[] args) {
System.out.println("替换为:I am ReplacedMethod");
return null;
}
}
public class ChangeMethod {
public void change() {
System.out.println("I am ChangeMethod.change()");
}
}
xml配置
<bean id="replacedMethod" class="org.spring.replacedmethod.ReplacedMethod"></bean>
<bean id="changeMethod" class="org.spring.replacedmethod.ChangeMethod">
<replaced-method name="change" replacer="replacedMethod"></replaced-method>
</bean>
*/
//1、lookup-method被封装成new LookupOverride(methodName, beanRef)
//2、replaced-method被封装成new ReplaceOverride(name, callback), callback对应replacer属性值
//3、LookupOverride和ReplaceOverride都继承了抽象类MethodOverride
//4、该处代码的功能是将AbstractBeanDefinition中的集合属性MethodOverrides的MethodOverride的字段overloaded值设置为false
// MethodOverride.setOverloaded(false); 该参数只影响<replaced-method>,<lookup-method>只匹配无参的方法
// 一旦设置为false表示被替换的方法没有重载,<replaced-method>匹配方法时不再做参数类型匹配
/*
public class LookupOverride extends MethodOverride {
// ...其它代码代码(略)
@Override
public boolean matches(Method method) {
return (method.getName().equals(getMethodName()) && method.getParameterTypes().length == 0);
}
// ...其它代码代码(略)
}
public class ReplaceOverride extends MethodOverride {
// ...其它代码代码(略)
@Override
public boolean matches(Method method) {
if (!method.getName().equals(getMethodName())) {
return false;
}
if (!isOverloaded()) { //MethodOverride.setOverloaded(false)作用于此处
return true;
}
// 参数类型匹配
if (this.typeIdentifiers.size() != method.getParameterTypes().length) {
return false;
}
for (int i = 0; i < this.typeIdentifiers.size(); i++) {
String identifier = this.typeIdentifiers.get(i);
if (!method.getParameterTypes()[i].getName().contains(identifier)) {
return false;
}
}
return true;
}
// ...其它代码代码(略)
}
*/
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//1、前后置处理器InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
//2、后后置处理器BeanPostProcessor.postProcessAfterInitialization(existingBean, beanName)
//3、后置处理器如果有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);
}
//分析流程 节点2
// 进入核心流程doCreateBean()
Object beanInstance = doCreateBean(beanName, mbd, args);
return beanInstance;
}
//分析流程 节点2
//createBean()方法做准备工作
//doCreateBean()方法才是真正创建bean实例的地方
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//分析流程 节点3
//创建BeanWrapper对象,同时会在BeanWrapper对象中创建bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//刚刚创建出来的bean实例,此时<property>中的属性值还未赋值给bean对象
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
//执行后置处理器MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
//由于此时的bean实例刚刚创建出来,可以通过此处的后置处理器修改BeanDefinition的内容,从而达到修改bean属性的目的
//例如:子类AutowiredAnnotationBeanPostProcessor处理注解@Autowired字段,经过该过程,扫描bean中的@Autowired字段,然后收集起来,为后面属性赋值做准备
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//如果bean是单例的,则将刚刚创建出来的bean实例放入缓存中,解决循环依赖
addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//1、在属性赋值前会执行后置处理器:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))
//此时可以修改bean实例对象,如果后置处理器处理后返回false,则populateBean方法流程终止,不会进行下面的属性装配工作
//2、在属性赋值前会执行后置处理器InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
// 例如子类AutowiredAnnotationBeanPostProcessor处理注解@Autowired字段,经过该过程,将会为@Autowired字段赋值
//3、将<property>中的属性值赋值给bean对象,<property>被封装在MutablePropertyValues集合对象中,单个<property>对应PropertyValue对象
//4、如果当前bean依赖其他bean,但是在<property>又未指定依赖的bean,则通过反射bean实例查找setXXX()方法,
// 如果是byName装配方式,通过BeanFactory.getBean("XXX")寻找bean,此时仅有一个
// 如果是byType装配方式,通过BeanFactory.getBean(XXX.class)寻找bean,此时可能会有多个,选择最优的一个,如果无法选出则会报错
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//1、如果bean实现了Aware接口(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware),通过setXXX方法将对应Aware内容注入进bean
//2、执行后置处理器BeanPostProcessor.postProcessBeforeInitialization(existingBean, beanName),在bean的init-method方法执行前可做额外工作
//3、调用bean的init-method方法
//4、执行后置处理器BeanPostProcessor.postProcessAfterInitialization(existingBean, beanName),在bean的init-method方法执行后可做额外工作
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
// ...上抛异常代码(略)
}
else {
// ...上抛异常代码(略)
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//检查depends-on依赖关系,检查是否存在循环依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// ...上抛异常代码(略)
}
}
}
}
try {
//如果bean有销毁关闭方法的话,将bean缓存工厂的Map<String, Object> disposableBeans
//此处功能了解的不太细
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
// ...上抛异常代码(略)
}
return exposedObject;
}
//分析流程 节点4
//创建BeanWrapper对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//将AbstractBeanDefinition中的beanClass字段值由String转为Class类型
//Object beanClass = "XXX.XXX.BeanName" ==> Object beanClass = Class.forName("XXX.XXX.BeanName")
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
// ...上抛异常代码(略)
}
if (mbd.getFactoryMethodName() != null) {
//通过工厂方法factory-method创建bean实例
/*
<bean id="factoryMethodBean" class="org.spring.factorymethod.FactoryMethodBean"/>
<bean id="user" class="org.spring.factorymethod.User" factory-bean="factoryMethodBean" factory-method="getUser">
<property name="name" value="zhangsan"></property>
</bean>
<bean id="user2" class="org.spring.factorymethod.StaticFactoryMethodBean" factory-method="getUser">
<property name="name" value="zhangsan"></property>
</bean>
*/
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 当bean有多个有参构造函数时,需要根据xml配置进行匹配合适的构成函数
//匹配过程是个耗时工作,需要将匹配的构成函数对象缓存到mbd.resolvedConstructorOrFactoryMethod
//当bean是非单例模式时才会走此分支,像scope="prototype",因为单例bean的实例创建好后直接缓存到map中,无需走createBean方法()
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {//为true代表已经解析过
if (autowireNecessary) {
//分析流程 节点5
//有参的构造函数
return autowireConstructor(beanName, mbd, null, null);
}
else {
//分析流程 节点6
//无参的构造函数
return instantiateBean(beanName, mbd);
}
}
//----------------------------------------------
// 如果是第一次匹配构造函数,也就是缓存中不存在
//---------------------------------------------
//执行后置处理器SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
//通过后置处理器确定候选构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//条件:后置处理器处理后构造函数列表不为空 || bean的装配模式是AUTOWIRE_CONSTRUCTOR
// || xml配置了<constructor-arg> || 调用方传入了参数值
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//分析流程 节点6
//匹配有参构造函数,然后创建bean对象
return autowireConstructor(beanName, mbd, ctors, args);
}
//分析流程 节点6
// 利用无参构造函数实例化.
return instantiateBean(beanName, mbd);
}
//分析流程 节点5
//匹配有参构造函数,然后创建bean对象,工作委托给ConstructorResolver处理
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
//核心流程代码,下面接着分析ConstructorResolver
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
//分析流程 节点6
// 利用无参构造函数实例化.
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) { //访问权限代码
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
//分析流程 节点7
//实例化bean对象
/*
此处并未直接通过Constructor.newInstance(args)实例化bean
是因为<look-up>、<replace-method>需要代理对象做单独处理
*/
//getInstantiationStrategy()为CglibSubclassingInstantiationStrategy对象
//SimpleInstantiationStrategy是CglibSubclassingInstantiationStrategy父类
//instantiate方法在SimpleInstantiationStrategy实现
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
//获取InstantiationStrategy实例
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
}
构造函数匹配入口:ConstructorResolver
class ConstructorResolver {
//分析流程 节点1
//匹配bean构造函数,创建BeanWrapperImpl对象和bean对象
public BeanWrapper autowireConstructor(
final String beanName, final RootBeanDefinition mbd, Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
//BeanWrapperImpl实现了PropertyEditorRegistry是个属性注册编辑器注册中心
//将bean工厂中自定义的属性注册编辑器注册到BeanWrapperImpl对象中
//后面装配bean属性值时,将配置的值转化为bean对象属性真实的类型,例如将字符串"2020-01-01"转为Date类型
this.beanFactory.initBeanWrapper(bw);
//存储匹配成功的构造函数对象
Constructor<?> constructorToUse = null;
//存储匹配成功的构造函数参数对象,Holder携带者对象
//argsHolderToUse = argsHolder;
ArgumentsHolder argsHolderToUse = null;
//存储匹配成功的构造函数参数对象
//argsToUse = argsHolder.arguments;
Object[] argsToUse = null;
if (explicitArgs != null) { //调用端直接提供参数,则用调用端传入的参数对象
//beanFactory.getBean("person", Person.class, new Object[]{"zhangsan", 7});
//{"zhangsan", 7}为调用端传入的参数对象
argsToUse = explicitArgs;
}
else { //调用端未传入参数,检查缓存,匹配工作很耗时,需将匹配后构造函数对象、参数对象存到BeanDefinition缓存
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//获取缓存的构造函数对象
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 获取缓存的参数对象数组
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
if (constructorToUse == null) { //缓存中不存在构造函数
// <bean id="xx" class="XXX" autowire="constructor"></bean>
//构建bean对象时,如果构造函数参数依赖其他bean,装配模式是否为"constructor",默认情况否
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
//期望匹配构造函数的参数个数
int minNrOfArgs;
if (explicitArgs != null) {
//如果调用端传入参数,则期望参数个数就是传入参数的个数
//beanFactory.getBean("person", Person.class, new Object[]{"zhangsan", 7});
minNrOfArgs = explicitArgs.length;
}
else {
//如果调用端未传入参数,取值为<bean>元素中<constructor-arg>元素的个数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
//将BeanDefinition中的构造函数信息放到临时对象resolvedValues中,此处new对象,后面使用
resolvedValues = new ConstructorArgumentValues();
//<bean>元素的子元素<constructor-arg>存放在BeanDefinition的ConstructorArgumentValues中
/**
ConstructorArgumentValues两个属性:
Map<Integer, ValueHolder> indexedArgumentValues, key为参数位置下标
List<ValueHolder> genericArgumentValues
*/
/**
<bean id="person" class="org.spring.xml.bean.Person" scope="prototype">
<constructor-arg name="email" value="lisi@123.com"></constructor-arg>
<constructor-arg name="age" value="12" index="1"></constructor-arg>
<constructor-arg name="name" value="lisi"></constructor-arg>
</bean>
1、带index属性的age属性存入genericArgumentValues
2、不带index属性的email和name属性存入genericArgumentValues
*/
//获取minNrOfArgs为<constructor-arg>元素在<bean>元素中的数量
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 如果后置处理器SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName).
//chosenCtors数据来源于上游调用方法AbstractAutowireCapableBeanFactory.createBeanInstance()
// 指定了构造函数范围,则chosenCtors不为空
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) { //未指定构造函数,通过反射获取bean类的所有构造函数对象
Class<?> beanClass = mbd.getBeanClass();
try {
//获取构造函数对象列表
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
// ...上抛异常代码(略)
}
}
//将候选构造函数列表candidates排序,返回类型为public优先,次之是函数参数越多优先级越高
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
//存储匹配过程中的错误信息
List<Exception> causes = null;
//循环上面圈定的候选构造函数对象列表,和配置中的<constructor-arg>构造信息相互匹配
for (int i = 0; i < candidates.length; i++) {
//获取单个候选的构造函数对象
Constructor<?> candidate = candidates[i];
//获取单个候选的构造函数参数对象列表
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
//构造函数参数个数小于期望参数个数,则不符合条件,跳过
if (paramTypes.length < minNrOfArgs) {
continue;
}
/**
如果候选函数参数列表和配置信息<constructor-arg>列表匹配成功的话
将配置信息<constructor-arg>存放到argsHolder中
*/
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
//获取候选函数参数名称列表
String[] paramNames = null;
/**
@ConstructorProperties({"name", "name"})
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
*/
if (constructorPropertiesAnnotationAvailable) {//通过注解@ConstructorProperties查找参数名
paramNames = ConstructorResolver.ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
}
if (paramNames == null) {//通过工具类ParameterNameDiscoverer获取参数名称
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//分析流程 节点2
//将候选的构造函数参数类型paramTypes列表,参数名称列表paramNames传入
//和配置中的参数列表进行匹配,此时配置中的参数信息存在于临时变量resolvedValues中
argsHolder = createArgumentArray(
beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (i == candidates.length - 1 && constructorToUse == null) { //匹配到最后一个未匹配上,进行异常抛出
if (causes != null) {
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
}
throw ex;
}
else { //中间匹配过程中发生错误,则进行匹配下一个候选构造函数,异常记录一下
if (causes == null) {
causes = new LinkedList<Exception>();
}
causes.add(ex);
continue;
}
}
}
else { //xml配置中<bean>元素下不存在<constructor-arg>元素
//候选的构造函数参数个数和调用端传入的参数个数不一样,则跳过,进入下一个候选构造函数
if (paramTypes.length != explicitArgs.length) {
continue;
}
//创建ArgumentsHolder对象,参数为调用端传入的参数对象数组
argsHolder = new ArgumentsHolder(explicitArgs);
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
///匹配到最后一个未匹配上,进行异常抛出
// ...上抛异常代码(略)
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null) {
//调用未传入参数的情况下,缓存匹配成功的构造函数对象
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
Object beanInstance;
if (System.getSecurityManager() != null) { //访问权限代码
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
}
}, beanFactory.getAccessControlContext());
}
else {
//分析流程 节点3
//实例化bean对象
/*
此处并未直接通过Constructor.newInstance(args)实例化bean
是因为<look-up>、<replace-method>需要代理对象做单独处理
getInstantiationStrategy()为CglibSubclassingInstantiationStrategy对象
SimpleInstantiationStrategy是CglibSubclassingInstantiationStrategy的父类
instantiate方法在SimpleInstantiationStrategy实现
*/
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
//将实例化后的bean对象放入BeanWrapper
bw.setWrappedInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
// ...上抛异常代码(略)
}
}
/**
* 候选构造函数参数匹配
*
* @param resolvedValues
* 对应BeanDefinition中的ConstructorArgumentValues
* @param bw
* BeanWrapper对象
* @param paramTypes
* 候选构造函数参数类型列表
* @param paramNames
* 候选构造函数参数类型列表
* @param methodOrCtor
* 候选的构造函数或工厂方法
* @param autowiring
* <bean id="xxx" class="XXX" autowire="constructor">
* bean的依赖注入的装配方式
* @return
* @throws UnsatisfiedDependencyException
*/
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Object methodOrCtor,
boolean autowiring) throws UnsatisfiedDependencyException {
//方法类型,除了通过构造函数创建bean对象,还可以通过工厂方法创建.参考:<bean id="xx" class="XXX" factory-bean="factoryBean" factory-method="fMethod">
String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
//属性值转换,参考优快云博文《Spring IOC 之 属性注册编辑器PropertyEditorRegistry源码》
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
this.beanFactory.getCustomTypeConverter() : bw);
//存储匹配成功的参数对象列表,数据来源于resolvedValues
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
//存储匹配成功的参数对象列表
/*
<bean id="person" class="org.spring.xml.bean.Person" scope="prototype">
<constructor-arg name="name" value="lisi"/>
<constructor-arg name="email" value="lisi@123.com"/>
<constructor-arg name="age" value="12"/>
</bean>
假如第一个候选参数匹配成功了<constructor-arg name="name" value="lisi"/>
将<constructor-arg name="name" value="lisi"/>对应的ValueHolder放入usedValueHolders;
第二个候选参数又匹配成功了<constructor-arg name="name" value="lisi"/>
但是这时发现usedValueHolders中已经存在了,所有不允许第二个候选参数使用
<constructor-arg name="name" value="lisi"/>
*/
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
//循环候选构造函数参数列表
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
//获取候选参数类型
Class<?> paramType = paramTypes[paramIndex];
//获取候选参数名称
String paramName = (paramNames != null ? paramNames[paramIndex] : null);
//候选参数类型、参数名称 与 resolvedValues中的构造函数参数信息进行匹配
//核心流程,一会单独进一步分析 参考:ConstructorArgumentValues分析
ConstructorArgumentValues.ValueHolder valueHolder =
resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
if (valueHolder == null && !autowiring) { //未匹配成功生成一个类似空的valueHolder
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
if (valueHolder != null) {
//匹配成功,存入usedValueHolders,用于校验,防止下一个候选参数使用这个valueHolder
usedValueHolders.add(valueHolder);
//获取参数在配置中的值,一般都是string类型
Object originalValue = valueHolder.getValue();
Object convertedValue;
/*
配置中的参数值可能需要转换一下,例如一个参数的类型是Date
而配置为<constructor-arg name="birthDate" value="2020-01-01"/>
则需要将字符串"2020-01-01"转为Date类型
*/
if (valueHolder.isConverted()) { //如果已经转换过
//获取参数在配置中的值
convertedValue = valueHolder.getConvertedValue();
//匹配成功的参数值放入ArgumentsHolder args的preparedArguments中
args.preparedArguments[paramIndex] = convertedValue;
}
else { //如果未转换
ConstructorArgumentValues.ValueHolder sourceHolder =
(ConstructorArgumentValues.ValueHolder) valueHolder.getSource();
Object sourceValue = sourceHolder.getValue();
try {
//转化参数属性值
convertedValue = converter.convertIfNecessary(originalValue, paramType,
MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex));
args.resolveNecessary = true;
//匹配成功的参数原始值放入ArgumentsHolder args的preparedArguments中
args.preparedArguments[paramIndex] = sourceValue;
}
catch (TypeMismatchException ex) {
// ...上抛异常代码(略)
}
}
//匹配成功的参数真实值存入ArgumentsHolder args的arguments中
args.arguments[paramIndex] = convertedValue;
//匹配成功的参数原始值存入ArgumentsHolder args的arguments中
args.rawArguments[paramIndex] = originalValue;
}
else {
/*
假如构造函数参数中,其中一个参数为其他的bean实例,通知在xml配置中又未指定同时bean的装配模式为constructor
例如:
java代码:
public class Student {
private String grade;
private String clazz;
private Person person;
public Student(String grade, String clazz, Person person) {
this.grade = grade;
this.clazz = clazz;
this.person = person;
}
}
xml配置:
<bean id="person" class="org.spring.xml.bean.Person">
<constructor-arg name="name" value="lisi"></constructor-arg>
<constructor-arg name="email" value="lisi@123.com"></constructor-arg>
<constructor-arg name="age" value="12" index="1"></constructor-arg>
</bean>
<bean id="student" class="org.spring.xml.bean.Student" autowire="constructor">
<constructor-arg name="grade" value="1年级"/>
<constructor-arg name="clazz" value="2班"></constructor-arg>
</bean>
Student构造函数依赖Person,但是xml配置中并没有person属性,但是在实际执行中会自动为person赋值
也就是下面的代码所要做的工作
*/
if (!autowiring) {
// ...上抛异常代码(略)
}
try {
//寻找参数类型为bean的构造函数参数
MethodParameter param = MethodParameter.forMethodOrConstructor(methodOrCtor, paramIndex);
//解析参数类型为bean的构造函数参数
Object autowiredArgument = resolveAutowiredArgument(param, beanName, autowiredBeanNames, converter);
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
args.resolveNecessary = true;
}
catch (BeansException ex) {
// ...上抛异常代码(略)
}
}
}
//依赖的参数是个bean对象,则存入bean工厂的依赖关系中
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
}
return args;
}
}
构造函数参数匹配入口:ConstructorArgumentValues
/**
<bean id="person" class="org.spring.xml.bean.Person" scope="prototype">
<constructor-arg name="email" value="lisi@123.com"></constructor-arg>
<constructor-arg name="age" value="12" index="1"></constructor-arg>
<constructor-arg name="name" value="lisi"></constructor-arg>
</bean>
<bean>元素的子元素<constructor-arg>存放在BeanDefinition的ConstructorArgumentValues中
ConstructorArgumentValues两个属性:
Map<Integer, ValueHolder> indexedArgumentValues, key为参数位置下标
List<ValueHolder> genericArgumentValues
1、带index属性的age属性存入genericArgumentValues
2、不带index属性的email和name属性存入genericArgumentValues
*/
public class ConstructorArgumentValues {
private Map<ValueHolder> indexedArgumentValues = new LinkedHashMap<>(0);
private List<ValueHolder> genericArgumentValues = new LinkedList<ValueHolder>();
//分析核心流程 -节点1
public ValueHolder getArgumentValue(int index, Class<?> requiredType, String requiredName, Set<ValueHolder> usedValueHolders) {
//分析核心流程 -节点2
//从indexedArgumentValues通过参数的位置下标获取构造函数参数信息
ValueHolder valueHolder = getIndexedArgumentValue(index, requiredType, requiredName);
if (valueHolder == null) {
//分析核心流程 -节点3
//从genericArgumentValues获取构造函数参数信息
valueHolder = getGenericArgumentValue(requiredType, requiredName, usedValueHolders);
}
return valueHolder;
}
//分析核心流程 -节点2
//候选的参数类型和参数名称与indexedArgumentValues进行匹配对比
public ValueHolder getIndexedArgumentValue(int index, Class<?> requiredType, String requiredName) {
//从indexedArgumentValues通过参数的位置下标获取构造函数参数信息
ValueHolder valueHolder = this.indexedArgumentValues.get(index);
if (valueHolder != null &&
(valueHolder.getType() == null ||
(requiredType != null && ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) &&
(valueHolder.getName() == null ||
(requiredName != null && requiredName.equals(valueHolder.getName())))) {
return valueHolder;
}
return null;
}
//分析核心流程 -节点3
//候选的参数类型和参数名称与genericArgumentValues进行匹配对比
public ValueHolder getGenericArgumentValue(Class<?> requiredType, String requiredName, Set<ValueHolder> usedValueHolders) {
for (ValueHolder valueHolder : this.genericArgumentValues) {
//一个候选参数于当前valueHolder匹配成功,对应的valueHolder放入usedValueHolders
//下一个候选参数不能再使用当前valueHolder
if (usedValueHolders != null && usedValueHolders.contains(valueHolder)) {
continue;
}
//valueHolder参数名称与候选参数名称是否一样
if (valueHolder.getName() != null &&
(requiredName == null || !valueHolder.getName().equals(requiredName))) {
continue;
}
//valueHolder参数类型与候选参数类型是否一样
if (valueHolder.getType() != null &&
(requiredType == null || !ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) {
continue;
}
if (requiredType != null && valueHolder.getType() == null && valueHolder.getName() == null &&
!ClassUtils.isAssignableValue(requiredType, valueHolder.getValue())) {
continue;
}
return valueHolder;
}
return null;
}
}
构造函数匹配成功后,开始实例化bean对象:SimpleInstantiationStrategy
public class SimpleInstantiationStrategy implements InstantiationStrategy {
//通过无参构造函数实例化bean对象
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
if (beanDefinition.getMethodOverrides().isEmpty()) { //如果xml<bean>元素下面没有<lookup-method>和<replaced-method>
Constructor<?> constructorToUse;
synchronized (beanDefinition.constructorArgumentLock) {
constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = beanDefinition.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) { //安全访问代码
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//通过Constructor.newInstance()实例化bean对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 通过 CGLIB 创建bean实例.
//该方法在子类CglibSubclassingInstantiationStrategy中实现逻辑
return instantiateWithMethodInjection(beanDefinition, beanName, owner);
}
}
//通过有参参构造函数实例化bean对象
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
final Constructor<?> ctor, Object[] args) {
if (beanDefinition.getMethodOverrides().isEmpty()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
}
});
}
//通过Constructor.newInstance(args)实例化bean对象
return BeanUtils.instantiateClass(ctor, args);
}
else {
// 通过 CGLIB 创建bean实例.
//该方法在子类CglibSubclassingInstantiationStrategy中实现逻辑
return instantiateWithMethodInjection(beanDefinition, beanName, owner, ctor, args);
}
}
}
对<lookup-method> <replaced-method>额外处理:CglibSubclassingInstantiationStrategy
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
private static final int PASSTHROUGH = 0;
//<look-up>类型
private static final int LOOKUP_OVERRIDE = 1;
//<replace-method>类型
private static final int METHOD_REPLACER = 2;
// 通过 CGLIB 创建bean实例
protected Object instantiateWithMethodInjection(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Constructor<?> ctor, Object[] args) {
return new CglibSubclassCreator(beanDefinition, owner).instantiate(ctor, args);
}
//内部类
private static class CglibSubclassCreator {
private final RootBeanDefinition beanDefinition;
private final BeanFactory owner;
public CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
this.beanDefinition = beanDefinition;
this.owner = owner;
}
//创建bean class的代理对象
public Object instantiate(Constructor<?> ctor, Object[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setCallbackFilter(new CallbackFilterImpl());
enhancer.setCallbacks(new Callback[]{
NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(),
new ReplaceOverrideMethodInterceptor()
});
return (ctor != null ? enhancer.create(ctor.getParameterTypes(), args) : enhancer.create());
}
private class CglibIdentitySupport {
protected RootBeanDefinition getBeanDefinition() {
return beanDefinition;
}
@Override
public boolean equals(Object other) {
return (other.getClass().equals(getClass()) &&
((CglibIdentitySupport) other).getBeanDefinition().equals(beanDefinition));
}
@Override
public int hashCode() {
return beanDefinition.hashCode();
}
}
//CGLIB 创建 <look-up>类型的bean实例
private class LookupOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
// Cast is safe, as CallbackFilter filters are used selectively.
LookupOverride lo = (LookupOverride) beanDefinition.getMethodOverrides().getOverride(method);
return owner.getBean(lo.getBeanName());
}
}
//CGLIB 创建 <replace-method>类型的bean实例
private class ReplaceOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
ReplaceOverride ro = (ReplaceOverride) beanDefinition.getMethodOverrides().getOverride(method);
MethodReplacer mr = (MethodReplacer) owner.getBean(ro.getMethodReplacerBeanName());
return mr.reimplement(obj, method, args);
}
}
/**
* 过滤 CGLIB 拦截器,用于区分<look-up> <replace-method>
*/
private class CallbackFilterImpl extends CglibIdentitySupport implements CallbackFilter {
public int accept(Method method) {
MethodOverride methodOverride = beanDefinition.getMethodOverrides().getOverride(method);
if (methodOverride == null) {
return PASSTHROUGH;
}
else if (methodOverride instanceof LookupOverride) {
return LOOKUP_OVERRIDE;
}
else if (methodOverride instanceof ReplaceOverride) {
return METHOD_REPLACER;
}
throw new UnsupportedOperationException(
"Unexpected MethodOverride subclass: " + methodOverride.getClass().getName());
}
}
}
}
源码分析遗漏点:通过工厂方法创建bean。
<bean id="factoryMethodBean" class="org.spring.factorymethod.FactoryMethodBean"/> <bean id="user" class="org.spring.factorymethod.User" factory-bean="factoryMethodBean" factory-method="getUser"> <property name="name" value="zhangsan"></property> </bean> <bean id="user2" class="org.spring.factorymethod.StaticFactoryMethodBean" factory-method="getUser"> <property name="name" value="zhangsan"></property> </bean>调用链路AbstractAutowireCapableBeanFactory#createBeanInstance==》AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod
==>ConstructorResolver#instantiateUsingFactoryMethod,最后匹配工厂方法和匹配构造函数逻辑类似。
后置处理器在spring中占有非常重要位置,对涉及的后置处理器做个简单总结:
1、在createBean方法中,在doCreateBean()之前,有两个后置处理器
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
BeanPostProcessor.postProcessAfterInitialization(existingBean, beanName)==》与第7个后置处理器是同一个
第一个后置处理器的第一个参数是beanClass,第二个后置处理器的第一个参数是bean对象
影响:一旦该处创建出来bean实例,后面spring容器不在执行创建bean实例过程
2、在createBeanInstance方法中,实例化bean实例前,将要准备匹配构造函数时
SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
后置处理器返回Constructor<?>[]
影响:可以限制bean可匹配的候选构造函数范围,一般情况是反射beanClas获取候选构造函数列表,一旦后置处理器返回,则不再通过反射获取候选构造函数。
3、在doCreateBean方法中,BeanWrapper刚刚创建后,也是bean实例刚刚创建出来,此时属性值还未赋予bean实例
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
可改变BeanDefinition内容
影响:由于BeanDefinition被改变,会影响后面的属性赋予,比如:将bean属性的值重新改变
4、在populateBean方法中,在依赖自动装配前,此时属性值还未赋予bean实例
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName))
返回值为布尔值,参数是bean实例,因此可以改变bean实例内容。
影响:通过后置处理器给bean实例属性赋值,一旦后置处理器返回false,后面不再给bean实例组装属性值。
5、在populateBean方法中,在依赖自动装配后,此时属性值还未赋予bean实例
InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
可改变pvs内容,pvs为PropertyValues类型
影响:可以改变PropertyValues内容,影响后面真正给bean赋予的属性值内容
6、在initializeBean方法中,如果bean继承了Aware,此时刚刚设置完Aware,如果bean继承了InitializingBean,在方法afterPropertiesSet之前
如果<bean>有init-method属性,在init-method方法之前
BeanPostProcessor.postProcessBeforeInitialization(existingBean, beanName)
影响:可以改变bean实例的行为
7、在initializeBean方法中,如果bean继承了InitializingBean,在方法afterPropertiesSet之后,如果<bean>有init-method属性,在init-method方法之后
BeanPostProcessor.postProcessAfterInitialization(existingBean, beanName)
影响:可以改变bean实例的行为
====最后补充一下factory-method <lookup-method> <replaced-method>使用范例====
factory-method应用:
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<bean id="factoryMethodBean" class="org.spring.factorymethod.FactoryMethodBean"/>
<bean id="user" class="org.spring.factorymethod.User" factory-bean="factoryMethodBean" factory-method="getUser">
<property name="name" value="zhangsan"></property>
</bean>
<bean id="user2" class="org.spring.factorymethod.StaticFactoryMethodBean" factory-method="getUser">
<property name="name" value="zhangsan"></property>
</bean>
</beans>
java代码:
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
public class FactoryMethodBean {
private User user;
public User getUser() {
this.user = new User();
this.user.setName("zhangsan");
return user;
}
}
public class StaticFactoryMethodBean {
public static User getUser() {
User user = new User();
user.setName("lisi");
return user;
}
}
测试代码:
public static void main(String[] args) throws Exception { ClassPathResource resource = new ClassPathResource("spring-factorymethod.xml"); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); //reader.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); reader.loadBeanDefinitions(resource); User user = beanFactory.getBean("user", User.class); System.out.println(user); user = beanFactory.getBean("user2", User.class); System.out.println(user); }
执行结果:
<lookup-method>应用:
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="org.spring.lookup.User"/>
<bean id="student" class="org.spring.lookup.Student"/>
<bean id="lookUpBean" class="org.spring.lookup.LookUpBean">
<lookup-method name="getUser" bean="student" ></lookup-method>
</bean>
</beans>
java代码:
public class User {
public void say() {
System.out.println("I am User!!");
}
}
public class Student extends User {
@Override
public void say() {
System.out.println("I am student!!");
}
}
public class LookUpBean {
public User getUser() {
return null;
}
public void say() {
this.getUser().say();
}
}
测试代码:
public static void main(String[] args) { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); ClassPathResource resource = new ClassPathResource("spring-lookup.xml"); reader.loadBeanDefinitions(resource); LookUpBean lookUpBean = beanFactory.getBean("lookUpBean", LookUpBean.class); lookUpBean.say(); }
执行结果:
<replaced-method>应用:
xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="replacedMethod" class="org.spring.replacedmethod.ReplacedMethod"></bean>
<bean id="changeMethod" class="org.spring.replacedmethod.ChangeMethod">
<replaced-method name="change" replacer="replacedMethod">
<arg-type match="String"></arg-type>
</replaced-method>
</bean>
</beans>
java代码:
public class ChangeMethod {
public void change() {
System.out.println("I am ChangeMethod.change()");
}
public void change(String param1) {
System.out.println("I am ChangeMethod.change(param1)");
}
}
import org.springframework.beans.factory.support.MethodReplacer;
import java.lang.reflect.Method;
public class ReplacedMethod implements MethodReplacer {
@Override
public Object reimplement(Object obj, Method method, Object[] args) {
StringBuilder methodSign = new StringBuilder();
methodSign.append(method.getReturnType().getSimpleName()).append('#');
String clazzName = obj.getClass().getSimpleName();
methodSign.append(clazzName.substring(0, clazzName.indexOf("$"))).append('.');
methodSign.append(method.getName());
methodSign.append("(");
if(null != args && args.length > 0) {
StringBuilder paramSign = new StringBuilder();
for(Object argObj : args) {
paramSign.append(argObj.getClass().getSimpleName() + ", ");
}
methodSign.append(paramSign.substring(0, paramSign.length()-2));
}
methodSign.append(")");
System.out.println(methodSign + "==>被替换了!!");
return null;
}
}
测试代码:
public static void main(String[] args) { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); ClassPathResource resource = new ClassPathResource("spring-replacedmethod.xml"); reader.loadBeanDefinitions(resource); ChangeMethod changeMethod = beanFactory.getBean("changeMethod", ChangeMethod.class); changeMethod.change(); changeMethod.change("123"); }