Spring源码-源码层面讲解实例对象工厂方法、静态工厂方法、无参构造方法如何创建对象(从源头分析)

前置准备工作

factoryMethod.xml配置文件创建
bean标签,person是静态对象工厂方法;
person2是用的实例对象工厂;

<?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="com.mashibing.factoryMethod.PersonStaticFactory" factory-method="getPerson">
        <!--constructor-arg:可以为方法指定参数-->
        <constructor-arg value="123"></constructor-arg>
    </bean>
    <bean id="personInstanceFactory" class="com.mashibing.factoryMethod.PersonInstanceFactory"></bean>
    <bean id="person2" class="com.mashibing.factoryMethod.Person" factory-bean="personInstanceFactory" factory-method="getPerson">
        <constructor-arg value="wangwu"></constructor-arg>
    </bean>
</beans>

bean标签,person是静态对象工厂方法;

public class PersonStaticFactory {

    public static Person getPerson(String name){
        Person person = new Person();
        person.setId(1);
        person.setName(name);
        return person;
    }

    public static Person getPerson(int age){
        return new Person();
    }

    public static Person getPerson(String name,int id){
        Person person = new Person();
        person.setId(1);
        person.setName(name);
        return person;
    }
}

person2是用的实例对象工厂;

public class PersonInstanceFactory {
    public Person getPerson(String name){
        Person person = new Person();
        person.setId(1);
        person.setName(name);
        return person;
    }
}
public class Person {
    private int id;
    private String name;
    private int age;
    private String gender;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

启动方法

public class TestFactoryMethod {

    public static void main(String[] args) {

        ApplicationContext ac = new ClassPathXmlApplicationContext("factoryMethod.xml");
        Person person = ac.getBean("person", Person.class);
        System.out.println(person);
        Person person2 = ac.getBean("person2", Person.class);
        System.out.println(person2);
    }
}

解析配置文件factory-method和factory-bean标签

factory-method解析
调用链路

parseBeanDefinitionElement:537, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
parseBeanDefinitionElement:445, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
parseBeanDefinitionElement:410, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
processBeanDefinition:326, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
parseDefaultElement:199, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
parseBeanDefinitions:178, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
doRegisterBeanDefinitions:150, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
registerBeanDefinitions:97, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
registerBeanDefinitions:526, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
doLoadBeanDefinitions:397, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:341, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:310, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:190, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:234, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:197, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:267, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:150, AbstractXmlApplicationContext (org.springframework.context.support)
loadBeanDefinitions:102, AbstractXmlApplicationContext (org.springframework.context.support)
refreshBeanFactory:138, AbstractRefreshableApplicationContext (org.springframework.context.support)
obtainFreshBeanFactory:718, AbstractApplicationContext (org.springframework.context.support)
refresh:577, AbstractApplicationContext (org.springframework.context.support)
<init>:150, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:87, ClassPathXmlApplicationContext (org.springframework.context.support)
main:10, TestFactoryMethod (com.mashibing.factoryMethod)

可以看出这个标签解析之后,bean对象 factoryMethodName属性有值了;

    <bean id="person" class="com.mashibing.factoryMethod.PersonStaticFactory" factory-method="getPerson">
        <!--constructor-arg:可以为方法指定参数-->
        <constructor-arg value="123"></constructor-arg>
    </bean>

在这里插入图片描述
factory-method和factory-bean解析
调用链路

parseBeanDefinitionAttributes:663, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
parseBeanDefinitionElement:530, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
parseBeanDefinitionElement:445, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
parseBeanDefinitionElement:410, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
processBeanDefinition:326, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
parseDefaultElement:199, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
parseBeanDefinitions:178, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
doRegisterBeanDefinitions:150, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
registerBeanDefinitions:97, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
registerBeanDefinitions:526, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
doLoadBeanDefinitions:397, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:341, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:310, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:190, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:234, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:197, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:267, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:150, AbstractXmlApplicationContext (org.springframework.context.support)
loadBeanDefinitions:102, AbstractXmlApplicationContext (org.springframework.context.support)
refreshBeanFactory:138, AbstractRefreshableApplicationContext (org.springframework.context.support)
obtainFreshBeanFactory:718, AbstractApplicationContext (org.springframework.context.support)
refresh:577, AbstractApplicationContext (org.springframework.context.support)
<init>:150, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:87, ClassPathXmlApplicationContext (org.springframework.context.support)
main:10, TestFactoryMethod (com.mashibing.factoryMethod)

可以看到解析之后,bean里相关方法名和对象名已经有值了。
在这里插入图片描述

使用静态工厂方法创建对象

创建对象链路

createBeanInstance:1435, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:675, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:630, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:417, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 447981768 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$17)
getSingleton:370, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:414, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:260, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:993, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:1024, AbstractApplicationContext (org.springframework.context.support)
refresh:614, AbstractApplicationContext (org.springframework.context.support)
<init>:150, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:87, ClassPathXmlApplicationContext (org.springframework.context.support)
main:10, TestFactoryMethod (com.mashibing.factoryMethod)

创建person对象,静态工厂方法,后续会标志静态

    <bean id="person" class="com.mashibing.factoryMethod.PersonStaticFactory" factory-method="getPerson">
        <!--constructor-arg:可以为方法指定参数-->
        <constructor-arg value="123"></constructor-arg>
    </bean>

在这里插入图片描述
**instantiateUsingFactoryMethod方法:**这里会进else

// 从mbd中获取配置的FactoryBean名
		String factoryBeanName = mbd.getFactoryBeanName();
		// 如果factoryBeanName不为null
		if (factoryBeanName != null) {
			// 如果factoryBean名与beanName相同
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			// 从bean工厂中获取factoryBeanName所指的factoryBean对象
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			// 如果mbd配置为单例作用域 且 beanName已经在bean工厂的单例对象的高速缓存Map中
			if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
				// 这个时候意味着Bean工厂中已经有beanName的Bean对象,而这个还要生成多一个Bean名为BeanName的Bean对象,导致了冲突
				// 抛出ImplicitlyAppearedSingletonException,
				throw new ImplicitlyAppearedSingletonException();
			}
			// 获取factoryBean的Class对象
			factoryClass = factoryBean.getClass();
			// 设置isStatic为false,表示不是静态方法
			isStatic = false;
		}
		else {
			// It's a static factory method on the bean class.
			// 这是bean类上的静态工厂方法
			// 如果mbd没有指定bean类
			if (!mbd.hasBeanClass()) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"bean definition declares neither a bean class nor a factory-bean reference");
			}
			// 将factoryBean设为null
			factoryBean = null;
			// 指定factoryClass引用mbd指定的bean类
			factoryClass = mbd.getBeanClass();
			// 设置isStatic为true,表示是静态方法
			isStatic = true;
		}
instantiateUsingFactoryMethod:562, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:1634, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBeanInstance:1436, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)

静态工厂方法调用
ConstructorResolver类的instantiateUsingFactoryMethod方法开始获取工厂方法创建对象
该方法这里开始生成:

	// 使用factoryBean生成与beanName对应的Bean对象,并将该Bean对象保存到bw中
	bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));		

链路:

getPerson:6, PersonStaticFactory (com.mashibing.factoryMethod)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
instantiate:218, SimpleInstantiationStrategy (org.springframework.beans.factory.support)
instantiate:936, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:908, ConstructorResolver (org.springframework.beans.factory.support)

在这里插入图片描述
在这里插入图片描述

使用无参构造创建personInstanceFactory对象

该方法代码如下,默认会有一个无参构造,在实例化的时候会使用无参构造的形式:

public class PersonInstanceFactory {
    public Person getPerson(String name){
        Person person = new Person();
        person.setId(1);
        person.setName(name);
        return person;
    }
}

在这里插入图片描述

instantiateBean:1605, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBeanInstance:1495, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:675, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)

在这里插入图片描述
bd.hasMethodOverrides()是false取反是true,所以不会用cglib来动态代理,这里会直接获取默认构造方法实例化

/**
	 * 如果发现是有方法重载的,就需要用cglib来动态代理,如果没有就直接获取默认构造方法实例化
	 */
	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// bd对象定义中,是否包含MethodOverride列表,spring中有两个标签参数会产生MethodOverrides,分别是lookup-method,replaced-method
		// 没有MethodOverrides对象,可以直接实例化
		if (!bd.hasMethodOverrides()) {
			// 实例化对象的构造方法
			Constructor<?> constructorToUse;
			// 锁定对象,使获得实例化构造方法线程安全
			synchronized (bd.constructorArgumentLock) {
				// 查看bd对象里使用否含有构造方法
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				// 如果没有
				if (constructorToUse == null) {
					// 从bd中获取beanClass
					final Class<?> clazz = bd.getBeanClass();
					// 如果要实例化的beanDefinition是一个接口,则直接抛出异常
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						// 获取系统安全管理器
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							// 获取默认的无参构造器
							constructorToUse = clazz.getDeclaredConstructor();
						}
						// 获取到构造器之后将构造器赋值给bd中的属性
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			// 通过反射生成具体的实例化对象
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			// 必须生成cglib子类
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

可以看出这里是无参构造形式,实例化对象
在这里插入图片描述
** BeanUtils.instantiateClass(constructorToUse);**

	/**
	 * 调用构造函数实例化
	 *使用给定构造函数实例化类的方便方法。
	 * 请注意,如果给定不可访问(即非公共)构造函数,则此方法尝试将构造函数设置为可访问的,并支持带有可选参数和默认值的Kotlin类
	 */
	public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			ReflectionUtils.makeAccessible(ctor);
			if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
				return KotlinDelegate.instantiateClass(ctor, args);
			}
			else {
				Class<?>[] parameterTypes = ctor.getParameterTypes();
				Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
				Object[] argsWithDefaultValues = new Object[args.length];
				//获得参数
				for (int i = 0 ; i < args.length; i++) {
					if (args[i] == null) {
						Class<?> parameterType = parameterTypes[i];
						argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
					}
					else {
						argsWithDefaultValues[i] = args[i];
					}
				}
				return ctor.newInstance(argsWithDefaultValues);
		}
		}
		catch (InstantiationException ex) {
			throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
		}
		catch (IllegalAccessException ex) {
			throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
		}
		catch (IllegalArgumentException ex) {
			throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
		}
		catch (InvocationTargetException ex) {
			throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
		}
	}

使用实例对象工厂方法创建person2对象

    <bean id="person2" class="com.mashibing.factoryMethod.Person" factory-bean="personInstanceFactory" factory-method="getPerson">
        <constructor-arg value="wangwu"></constructor-arg>
    </bean>

在这里插入图片描述

**instantiateUsingFactoryMethod方法:**这里会进if

// 从mbd中获取配置的FactoryBean名
		String factoryBeanName = mbd.getFactoryBeanName();
		// 如果factoryBeanName不为null
		if (factoryBeanName != null) {
			// 如果factoryBean名与beanName相同
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			// 从bean工厂中获取factoryBeanName所指的factoryBean对象
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			// 如果mbd配置为单例作用域 且 beanName已经在bean工厂的单例对象的高速缓存Map中
			if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
				// 这个时候意味着Bean工厂中已经有beanName的Bean对象,而这个还要生成多一个Bean名为BeanName的Bean对象,导致了冲突
				// 抛出ImplicitlyAppearedSingletonException,
				throw new ImplicitlyAppearedSingletonException();
			}
			// 获取factoryBean的Class对象
			factoryClass = factoryBean.getClass();
			// 设置isStatic为false,表示不是静态方法
			isStatic = false;
		}
		else {
			// It's a static factory method on the bean class.
			// 这是bean类上的静态工厂方法
			// 如果mbd没有指定bean类
			if (!mbd.hasBeanClass()) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"bean definition declares neither a bean class nor a factory-bean reference");
			}
			// 将factoryBean设为null
			factoryBean = null;
			// 指定factoryClass引用mbd指定的bean类
			factoryClass = mbd.getBeanClass();
			// 设置isStatic为true,表示是静态方法
			isStatic = true;
		}

获取到的实例工厂对象的对象以及类型,
在这里插入图片描述

			// 如果candidateList为null
			if (candidates == null) {
				// 让candidateList引用一个新的ArrayList
				candidates = new ArrayList<>();
				// 根据mbd的是否允许访问非公共构造函数和方法标记【RootBeanDefinition.isNonPublicAccessAllowed】来获取factoryClass的所有候选方法
				Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
				// 遍历rawCandidates,元素名为candidate
				for (Method candidate : rawCandidates) {
					// 如果candidate的修饰符与isStatic一致且candidate有资格作为mdb的工厂方法
					if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
						// 将candidate添加到candidateList中
						candidates.add(candidate);
					}
				}
			}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

instantiate:218, SimpleInstantiationStrategy (org.springframework.beans.factory.support)
instantiate:936, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:908, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:1634, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)

在这里插入图片描述
调用实例对象的工厂方法创建对象!

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值