Spring源码:手写SpringDI

我们是在实现了SpringIOC的基础上,进行拓展,IOC实现源码可以查看:手写SpringIOC

一、分析

DI是依赖注入(Dependency Injection)的缩写,是一种通过外部注入来管理组件之间依赖关系的设计模式。

本质就是赋值,给bean对象的成员变量赋值

赋值的两种情况

  • 有参构造函数赋值
  • 属性赋值

值的类型?

  • Java中支持的类型
  • Bean依赖

二、实现

1、构造注入

1)分析

通过构造方法创建实例,需要传入对应参数

  • 一般直接代码实现,直接赋值,P p = new P(xxx)
  • 在IoC中,通过反射

需要获取构造参数,可能有多个,还要保证顺序,怎么存储?

可能的参数有数字、字符串、bean依赖…
可以通过List集合来存储,添加元素的顺序就是构造参数的顺序,但是bean依赖还没有创建对应的对象,需要维护一个自定义对象,来绑定关系

2)版本1

原来已经有无参构造方法,现在我们要添加有参构造方法

BeanReference

新增一个BeanReference类,来说明bean依赖,具体依赖哪个类型的bean

public class BeanReference {

	private String beanName;

	private Class<?> type;

	public BeanReference(String beanName) {
		this.beanName = beanName;
	}

	public BeanReference(Class<?> type) {
		this.type = type;
	}

	public String getBeanName() {
		return beanName;
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}

	public Class<?> getType() {
		return type;
	}

	public void setType(Class<?> type) {
		this.type = type;
	}
}
BeanDefinition

支持构造注入

List<?> getConstructorArgumentValues();
void setConstructorArgumentValues(List<?> constructorArgumentValues);
GenericBeanDefinition

实现支持构造注入

private List<?> constructorArgumentValues;

@Override
public List<?> getConstructorArgumentValues() {
	return constructorArgumentValues;
}
@Override
public void setConstructorArgumentValues(List<?> constructorArgumentValues) {
	this.constructorArgumentValues = constructorArgumentValues;
}
DefaultBeanFactory
1、改造构造函数

原来的方法,只支持无参构造函数,已经不适用,需要支持有参构造函数

// 构造方法来构造对象:new BeanClass(xxx...)
private Object createInstanceByConstructor(BeanDefinition bd) throws Exception {
	// 1、获取参数值
	Object[] args = this.getConstructorArgumentValues(bd);
	// 2、确定调用什么构造方法来创建实例
	Constructor constructor = this.determineConstructor(bd, args);
	return constructor.newInstance(args);
}

获取参数值

private Object[] getConstructorArgumentValues(BeanDefinition bd) throws Exception {
	List<?> defs = bd.getConstructorArgumentValues();
	if (CollectionUtils.isEmpty(defs)) {
		return null;
	}
	Object[] values = new Object[defs.size()];
	int index = 0;
	for (Object originalValue : defs) {
		values[index++] = getOneArgumentRealValue(originalValue);
	}
	return values;
}

获取真正参数值,主要是处理BeanReference,得到真正的Bean实例

private Object getOneArgumentRealValue(Object originalValue) throws Exception {
	Object realValue = null;
	if (originalValue == null) {
		return realValue;
	}
	if (originalValue instanceof BeanReference) {
		//  处理bean引用
		BeanReference br = (BeanReference) originalValue;
		if (StringUtils.isNotBlank(br.getBeanName())) {
			realValue = this.getBean(br.getBeanName());
		} else if (br.getType() != null) {
			realValue = this.getBean(br.getType());
		}
	} else if (originalValue instanceof Object[]) {
		// 处理数组中的bean引用
		Object[] objects = (Object[]) originalValue;
		for (int i = 0; i < objects.length; i++) {
			if (objects[i] instanceof BeanReference) {
				objects[i] = getOneArgumentRealValue(objects[i]);
			}
		}
		realValue = objects;
	} else if (originalValue instanceof Collection) {
		// 处理集合中的bean引用
		if (originalValue instanceof Set) {
			Set set = (Set) originalValue;
			Iterator iterator = set.iterator();
			Set newSet = new HashSet();
			while (iterator.hasNext()) {
				Object next = iterator.next();
				if (next instanceof BeanReference) {
					iterator.remove();
					// set.add(getOneArgumentRealValue(next));
					newSet.add(getOneArgumentRealValue(next));
				}
			}
			set.addAll(newSet);
			realValue = set;
		} else if (originalValue instanceof List) {
			List list = (List) originalValue;
			for (int i = 0; i < list.size(); i++) {
				if (list.get(i) instanceof BeanReference) {
					list.set(i, getOneArgumentRealValue(list.get(i)));
				}
			}
			realValue = list;
		} else {
			realValue = originalValue;
		}
	} /*else if (originalValue instanceof Map) {
		// TODO 处理Map中的bean引用
	} */ else {
		realValue = originalValue;
	}
	return realValue;
}

确定调用什么构造方法来创建实例,先精确匹配(根据参数的类型进行精确匹配查找),再参数匹配(获得所有的构造方法,遍历,先判断参数数量,再依次比对形参类型与实参类型)

private Constructor<?> determineConstructor(BeanDefinition bd, Object[] args) throws Exception {
	// 无参数,就调用无参构造方法即可
	if (args == null) {
		return bd.getBeanClass().getConstructor(null);
	}
	Constructor<?> constructor = null;
	// 有参数,先精确匹配,匹配不到,再模糊匹配
	// 1、精确匹配
	Class<?>[] parameterTypes = new Class[args.length];
	for (int i = 0; i < args.length; i++) {
		parameterTypes[i] = args[i].getClass();
	}
	try {
		constructor = bd.getBeanClass().getConstructor(parameterTypes);
	} catch (Exception e) {
		// 这里可能找不到会报错,不用处理
	}
	// 2、参数匹配
	if (constructor == null) {
		Constructor<?>[] constructors = bd.getBeanClass().getConstructors();
		outer:
		for (Constructor<?> constructorTemp : constructors) {
			Class<?>[] tempParameterTypes = constructorTemp.getParameterTypes();
			// 参数列表个数一样
			if (tempParameterTypes.length == args.length) {
				for (int i = 0; i < tempParameterTypes.length; i++) {
					// 判断tempParameterTypes是否是其父类或者相同类
					if (!tempParameterTypes[i].isAssignableFrom(args[i].getClass())) {
						// 参数类型不一样,跳到下一个构造方法
						continue outer;
					}
				}
				constructor = constructorTemp;
				break outer;
			}
		}
	}
	// 3、还没找到,抛出异常提示
	if (constructor == null) {
		throw new Exception(bd + "不存在对应的构造方法");
	}
	return constructor;
}

如果我们是通过静态工厂方法或者成员工厂方法的方式来处理的,其实和构造参数依赖处理差不多

2、改造静态工厂方法
// 静态工厂方法:BeanClass.factoryMethodName(xxx...)
private Object createInstanceByStaticFactoryMethod(BeanDefinition bd) throws Exception {
	// 1、获取参数值
	Object[] args = this.getConstructorArgumentValues(bd);
	// 2、确定调用什么方法来执行获取示例
	Class<?> beanClass = bd.getBeanClass();
	Method m = this.determineMethod(bd, beanClass, args);
	return m.invoke(beanClass, args);
}

确定调用什么方法来创建实例,先精确匹配,后参数匹配

private Method determineMethod(BeanDefinition beanDefinition, Class<?> beanClass, Object[] args) throws Exception {
	Method targetMethod = null;
	String factoryMethodName = beanDefinition.getFactoryMethodName();
	// 1、精确匹配
	Class<?>[] parameterTypes = new Class[args.length];
	for (int i = 0; i < args.length; i++) {
		parameterTypes[i] = args[i].getClass();
	}
	try {
		targetMethod = beanClass.getMethod(factoryMethodName, parameterTypes);
	} catch (Exception e) {
		// 这里可能找不到会报错,不用处理,走后续的模糊匹配即可
	}
	// 2、参数匹配
	if (targetMethod == null) {
		outer:
		for (Method method : beanClass.getMethods()) {
			if (Objects.equals(factoryMethodName, method.getName())) {
				continue;
			}
			Class<?>[] tempparameterTypes = method.getParameterTypes();
			if (parameterTypes.length == args.length) {
				for (int i = 0; i < parameterTypes.length; i++) {
					if (!tempparameterTypes[i].getClass().isAssignableFrom(args[i].getClass())) {
						continue outer;
					}
					targetMethod = method;
					break outer;
				}
			}
		}
	}
	// 3、还没找到,抛出异常提示
	if (targetMethod == null) {
		throw new Exception(beanDefinition + "不存在对应的方法");
	}
	return targetMethod;
}
3、改造工厂方法
// 工厂bean方式来构造对象:new FactoryBeanName().factoryMethodName(xxx...)
private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {
	// 1、获取工厂bean
	Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
	Class<?> factoryBeanClass = factoryBean.getClass();
	// 2、获取参数值
	Object[] args = this.getConstructorArgumentValues(bd);
	// 3、确定调用什么方法来执行获取示例
	Method m = this.determineMethod(bd, factoryBeanClass, args);
	return m.invoke(factoryBean, args);
}
4、改造getType

主要改造静态工厂方法和工厂方法,支持有参构造函数

@Override
public Class<?> getType(String name) throws Exception {
	BeanDefinition beanDefinition = this.getBeanDefinition(name);
	Class<?> beanClass = beanDefinition.getBeanClass();
	List<?> constructorArgumentValues = beanDefinition.getConstructorArgumentValues();
	if (beanClass != null) {
		// 如果是静态工厂方法,需要获取工厂创建的对象
		if (StringUtils.isNotBlank(beanDefinition.getFactoryMethodName())) {
			return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), this.listConverClassArr(constructorArgumentValues)).getReturnType();
		} else {
			return beanClass;
		}
	} else {
		// 其它情况是工厂方法的处理
		Method factoryMethod = beanDefinition.getFactoryMethod();
		if (factoryMethod != null) {
			return factoryMethod.getReturnType();
		} else {
			beanClass = getType(beanDefinition.getFactoryBeanName());
			return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), this.listConverClassArr(constructorArgumentValues)).getReturnType();
		}
	}
}

private Class<?>[] listConverClassArr(List<?> constructorArgumentValues) throws Exception {
	Class<?>[] res = new Class[constructorArgumentValues.size()];
	Class<?> type = null;
	if (constructorArgumentValues.isEmpty()) {
		return res;
	}
	for (int i = 0; i < constructorArgumentValues.size(); i++) {
		Object arg = constructorArgumentValues.get(i);
		if (arg instanceof cn.forlan.aop.beans.BeanReference) {
			cn.forlan.aop.beans.BeanReference beanReference = (cn.forlan.aop.beans.BeanReference) arg;
			if (StringUtils.isNotBlank(beanReference.getBeanName())) {
				type = this.getType(beanReference.getBeanName());
			} else {
				type = beanReference.getType();
			}
		} else {
			type = arg.getClass();
		}
		res[i] = type;
	}
	return res;
}

3)版本2

对于原型bean,可以缓存之前已经找到的构造方法和工厂方法

BeanDefinition

/**
 * 加缓存
 */
Constructor<?> getConstructor();
void setConstructor(Constructor<?> constructor);
Method getFactoryMethod();
void setFactoryMethod(Method factoryMethod);

GenericBeanDefinition

private Constructor<?> constructor;
private Method factoryMethod;

@Override
public Constructor<?> getConstructor() {
	return constructor;
}
@Override
public void setConstructor(Constructor<?> constructor) {
	this.constructor = constructor;
}
@Override
public Method getFactoryMethod() {
	return factoryMethod;
}
@Override
public void setFactoryMethod(Method factoryMethod) {
	this.factoryMethod = factoryMethod;
}

调整BeanFactory实现类DefaultBeanFactory

determineConstructor增加缓存逻辑

// 对于原型bean,从第二次开始获取bean实例时,可直接获得第一次缓存的构造方法。
constructor = bd.getConstructor();
if (constructor != null) {
	return constructor;
}

if (bd.isPrototype()) {
	// 对于原型bean,可以缓存找到的构造方法,方便下次构造实例对象
	bd.setConstructor(constructor);
}

determineMethod增加缓存逻辑

// 对于原型bean,从第二次开始获取方法时,可直接获得第一次缓存的方法
targetMethod = beanDefinition.getFactoryMethod();
if (targetMethod != null) {
	return targetMethod;
}

// 对于原型bean,可以缓存找到的方法,方便下次构造实例对象
if (beanDefinition.isPrototype()) {
	beanDefinition.setFactoryMethod(targetMethod);
}

4)版本3

主要解决循坏依赖的问题,对于构造注入,解决不了,但可以给异常提示,Spring中也是抛异常
存储创建对象,必须是ThreadLocal,避免多个线程的数据混乱,要线程隔离

主要改造doGetBean方法,创建前,记录正在创建的,创建完成,移除

// 存储创建中的对象
private ThreadLocal<Set<String>> buildingBeansRecordor = new ThreadLocal<>();

创建前,记录正在创建的

// 检测构造参数循环依赖
Set<String> buildingBeans = this.buildingBeansRecordor.get();
if (buildingBeans == null) {
    buildingBeans = new HashSet<>();
    this.buildingBeansRecordor.set(buildingBeans);
}
if (buildingBeans.contains(beanName)) {
    throw new Exception(beanName + " 循环依赖!" + buildingBeans);
}
// 记录正在创建的Bean
buildingBeans.add(beanName);

创建完成,移除

// 创建好实例后,移除创建中记录
buildingBeans.remove(beanName);

2、属性注入

1)版本1

创建好对象后,对属性进行赋值

使用实体类PropertyValue来记录

public class PropertyValue {

	private String name;

	private Object value;

	public PropertyValue(String name, Object value) {
		super();
		this.name = name;
		this.value = value;
	}

	public String getName() {
		return name;
	}

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

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}

}

BeanDefinition实现

List<PropertyValue> getPropertyValues();
void setPropertyValues(List<PropertyValue> propertyValues);

GenericBeanDefinition,实现类声明set和get方法

private List<PropertyValue> propertyValues;

@Override
public List<PropertyValue> getPropertyValues() {
	return propertyValues;
}

@Override
public void setPropertyValues(List<PropertyValue> propertyValues) {
	this.propertyValues = propertyValues;
}

调整DefaultBeanFactory实现,让doCreateInstance支持属性依赖,新增setPropertyDIValues方法

private Object doCreateInstance(BeanDefinition bd) throws Exception {
	Class<?> beanClass = bd.getBeanClass();
	Object instance = null;
	if (beanClass != null) {
		if (StringUtils.isBlank(bd.getFactoryMethodName())) {
			// 构造方法来构造对象
			instance = this.createInstanceByConstructor(bd);
		} else {
			// 静态工厂方法
			instance = this.createInstanceByStaticFactoryMethod(bd);
		}
	} else {
		// 工厂bean方式来构造对象
		instance = this.createInstanceByFactoryBean(bd);
	}
	// 支持属性依赖
	this.setPropertyDIValues(bd, instance);
	// 执行初始化方法
	this.doInit(bd, instance);
	return instance;
}

private void setPropertyDIValues(BeanDefinition bd, Object instance) throws Exception {
	if (CollectionUtils.isEmpty(bd.getPropertyValues())) {
		return;
	}
	for (PropertyValue pv : bd.getPropertyValues()) {
		if (StringUtils.isBlank(pv.getName())) {
			continue;
		}
		Class<?> clazz = instance.getClass();
		Field p = clazz.getDeclaredField(pv.getName());
		// 允许访问所有,包括private
		p.setAccessible(true);
		// 可能是引用对象,需要获取真正的值
		p.set(instance, this.getOneArgumentRealValue(pv.getValue()));
	}
}

2)版本2

属性依赖中也存在循环依赖问题,我们这个版本就是来解决循坏依赖的问题
在这里插入图片描述

解决:

  • 在非IoC场景很好解决
ForlanA a = new ForlanA();
ForlanB b = new ForlanB();
a.setForlanB(b);
b.setForlanA(a);
  • 在IoC中,可以通过提前暴露对象来解决

因为实例化和属性赋值分开了,可以通过提前暴露解决,实际上在属性注入时,已经有对象,只不过没有暴露出来,提前暴露出来即可

使用结构

private ThreadLocal<Map<String,Object>> earlyExposeBuildingBeans = new ThreadLocal<>();

主要改造的是doGetBean,新增getFromEarlyExposeBuildingBeans,拿到就直接返回,doCreateInstance新增传参beanName

private Object doGetBean(String beanName) throws Exception {
	Objects.requireNonNull(beanName, "beanName不能为空");

	Object instance = singletonBeanMap.get(beanName);
	if (instance != null) {
		return instance;
	}

	instance = this.getFromEarlyExposeBuildingBeans(beanName);
	if (instance != null) { //这是属性依赖时的循环引用,返回提前暴露的实例
		return instance;
	}

	BeanDefinition beanDefinition = this.getBeanDefinition(beanName);
	Objects.requireNonNull(beanDefinition, "beanDefinition不能为空");

	// 检测构造参数循环依赖
	Set<String> buildingBeans = this.buildingBeansRecordor.get();
	if (buildingBeans == null) {
		buildingBeans = new HashSet<>();
		this.buildingBeansRecordor.set(buildingBeans);
	}
	if (buildingBeans.contains(beanName)) {
		throw new Exception(beanName + " 循环依赖!" + buildingBeans);
	}
	// 记录正在创建的Bean
	buildingBeans.add(beanName);

	if (beanDefinition.isSingleton()) {
		synchronized (singletonBeanMap) {
			instance = singletonBeanMap.get(beanName);
			if (instance == null) {
				instance = doCreateInstance(beanName, beanDefinition);
				singletonBeanMap.put(beanName, instance);
			}
		}
	} else {
		instance = doCreateInstance(beanName, beanDefinition);
	}
	// 创建好实例后,移除创建中记录
	buildingBeans.remove(beanName);
	return instance;
}

private Object getFromEarlyExposeBuildingBeans(String beanName) {
	Map<String, Object> earlyExposeBuildingBeansMap = earlyExposeBuildingBeans.get();
	return earlyExposeBuildingBeansMap == null ? null : earlyExposeBuildingBeansMap.get(beanName);
}

改造doCreateInstance,支持beanName传参,在属性赋值前后加逻辑,提前暴露,赋值后,移除暴露对象

private void doEarlyExposeBuildingBeans(String beanName, Object instance) {
    Map<String,Object> earlyExposeBuildingBeansMap = earlyExposeBuildingBeans.get();
    if(earlyExposeBuildingBeansMap == null) {
        earlyExposeBuildingBeansMap = new HashMap<>();
        earlyExposeBuildingBeans.set(earlyExposeBuildingBeansMap);
    }
    earlyExposeBuildingBeansMap.put(beanName,instance);
}
private Object doCreateInstance(String beanName, BeanDefinition bd) throws Exception {
	Class<?> beanClass = bd.getBeanClass();
	Object instance = null;
	if (beanClass != null) {
		if (StringUtils.isBlank(bd.getFactoryMethodName())) {
			// 构造方法来构造对象
			instance = this.createInstanceByConstructor(bd);
		} else {
			// 静态工厂方法
			instance = this.createInstanceByStaticFactoryMethod(bd);
		}
	} else {
		// 工厂bean方式来构造对象
		instance = this.createInstanceByFactoryBean(bd);
	}
	// 赋值前暴露半成品对象
	this.doEarlyExposeBuildingBeans(beanName, instance);
	// 支持属性依赖
	this.setPropertyDIValues(bd, instance);
	// 赋完值移除
	this.removeEarlyExposeBuildingBeans(beanName);
	// 执行初始化方法
	this.doInit(bd, instance);
	return instance;
}

private void doEarlyExposeBuildingBeans(String beanName, Object instance) {
	Map<String,Object> earlyExposeBuildingBeansMap = earlyExposeBuildingBeans.get();
	if (earlyExposeBuildingBeansMap == null) {
		earlyExposeBuildingBeansMap = new HashMap<>();
		earlyExposeBuildingBeans.set(earlyExposeBuildingBeansMap);
	}
	earlyExposeBuildingBeansMap.put(beanName, instance);
}

private void removeEarlyExposeBuildingBeans(String beanName) {
	earlyExposeBuildingBeans.get().remove(beanName);
}

三、最终完整版本

在这里插入图片描述

PropertyValue

public class PropertyValue {

	private String name;

	private Object value;

	public PropertyValue(String name, Object value) {
		super();
		this.name = name;
		this.value = value;
	}

	public String getName() {
		return name;
	}

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

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}

}

BeanReference

/**
 * 用于依赖注入中描述bean依赖
 */
public class BeanReference {

	private String beanName;

	private Class<?> type;

	public BeanReference(String beanName) {
		this.beanName = beanName;
	}

	public BeanReference(Class<?> type) {
		this.type = type;
	}

	public String getBeanName() {
		return beanName;
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}

	public Class<?> getType() {
		return type;
	}

	public void setType(Class<?> type) {
		this.type = type;
	}
}

BeanDefinition

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

/**
 * bean定义接口
 */
public interface BeanDefinition {

    String SCOPE_SINGLETON = "singleton";

    String SCOPE_PROTOTYPE = "prototype";

    /**
     * 类
     */
    Class<?> getBeanClass();
    void setBeanClass(Class<?> beanClass);

    /**
     * Scope
     */
    void setScope(String scope);
    String getScope();

    /**
     * 是否单例
     */
    boolean isSingleton();

    /**
     * 是否原型
     */
    boolean isPrototype();

    /**
     * 工厂bean名
     */
    String getFactoryBeanName();
    void setFactoryBeanName(String factoryBeanName);

    /**
     * 工厂方法名
     */
    String getFactoryMethodName();
    void setFactoryMethodName(String factoryMethodName);

    /**
     * 初始化方法
     */
    String getInitMethodName();
    void setInitMethodName(String initMethodName);

    /**
     * 销毁方法
     */
    String getDestroyMethodName();
    void setDestroyMethodName(String destroyMethodName);

    /**
     * 是否为主要自动候选对象
     */
    boolean isPrimary();
    void setPrimary(boolean primary);

    /**
     * 校验bean定义的合法性,BeanClass和FactoryMethodName只能存在一个,定义了FactoryMethodName,必须指定FactoryMethodName
     */
    default boolean validate() {
        // 没定义类
        if (this.getBeanClass() == null) {
            // 工厂bean或工厂方法都没定义,则不合法
            if (StringUtils.isBlank(getFactoryBeanName()) || StringUtils.isBlank(getFactoryMethodName())) {
                return false;
            }
        }

        // 定义了类,又定义工厂bean,不合法
        if (this.getBeanClass() != null && StringUtils.isNotBlank(getFactoryBeanName())) {
            return false;
        }

        return true;
    }


	/**
	 * 支持有参构造注入
	 */
	List<?> getConstructorArgumentValues();
	void setConstructorArgumentValues(List<?> constructorArgumentValues);

	/**
	 * 加缓存
	 */
    Constructor<?> getConstructor();
    void setConstructor(Constructor<?> constructor);
    Method getFactoryMethod();
    void setFactoryMethod(Method factoryMethod);

    /**
     * 支持属性依赖
     */
    List<PropertyValue> getPropertyValues();
    void setPropertyValues(List<PropertyValue> propertyValues);

}

GenericBeanDefinition

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

public class GenericBeanDefinition implements BeanDefinition {

	public static final String SCOPE_DEFAULT = "";

	private Class<?> beanClass;

	private String scope = SCOPE_DEFAULT;

	private String factoryBeanName;

	private String factoryMethodName;

	private String initMethodName;

	private String destroyMethodName;

	private boolean primary;

	private List<?> constructorArgumentValues;

	private Constructor<?> constructor;

	private Method factoryMethod;

	private List<PropertyValue> propertyValues;

	@Override
	public Class<?> getBeanClass() {
		return beanClass;
	}

	@Override
	public void setBeanClass(Class<?> beanClass) {
		this.beanClass = beanClass;
	}

	@Override
	public String getScope() {
		return scope;
	}

	@Override
	public void setScope(String scope) {
		this.scope = scope;
	}

	/**
	 * 默认是单例
	 */
	@Override
	public boolean isSingleton() {
		return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
	}

	@Override
	public boolean isPrototype() {
		return SCOPE_PROTOTYPE.equals(this.scope);
	}

	@Override
	public String getFactoryBeanName() {
		return factoryBeanName;
	}

	@Override
	public void setFactoryBeanName(String factoryBeanName) {
		this.factoryBeanName = factoryBeanName;
	}

	@Override
	public String getFactoryMethodName() {
		return factoryMethodName;
	}

	@Override
	public void setFactoryMethodName(String factoryMethodName) {
		this.factoryMethodName = factoryMethodName;
	}

	@Override
	public String getInitMethodName() {
		return initMethodName;
	}

	@Override
	public void setInitMethodName(String initMethodName) {
		this.initMethodName = initMethodName;
	}

	@Override
	public String getDestroyMethodName() {
		return destroyMethodName;
	}

	@Override
	public void setDestroyMethodName(String destroyMethodName) {
		this.destroyMethodName = destroyMethodName;
	}

	@Override
	public boolean isPrimary() {
		return primary;
	}

	@Override
	public void setPrimary(boolean primary) {
		this.primary = primary;
	}

	@Override
	public List<?> getConstructorArgumentValues() {
		return constructorArgumentValues;
	}

	@Override
	public void setConstructorArgumentValues(List<?> constructorArgumentValues) {
		this.constructorArgumentValues = constructorArgumentValues;
	}

	@Override
	public Constructor<?> getConstructor() {
		return constructor;
	}

	@Override
	public void setConstructor(Constructor<?> constructor) {
		this.constructor = constructor;
	}

	@Override
	public Method getFactoryMethod() {
		return factoryMethod;
	}

	@Override
	public void setFactoryMethod(Method factoryMethod) {
		this.factoryMethod = factoryMethod;
	}

	@Override
	public List<PropertyValue> getPropertyValues() {
		return propertyValues;
	}

	@Override
	public void setPropertyValues(List<PropertyValue> propertyValues) {
		this.propertyValues = propertyValues;
	}

	@Override
	public String toString() {
		return "GenericBeanDefinition{" +
				"beanClass=" + beanClass +
				", factoryBeanName='" + factoryBeanName + '\'' +
				'}';
	}
}


BeanDefinitionRegistry

public interface BeanDefinitionRegistry {

	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws Exception;

	BeanDefinition getBeanDefinition(String beanName);

	boolean containsBeanDefinition(String beanName);
}

Beanfactory

import java.util.Map;

public interface Beanfactory {

	Object getBean(String name) throws Exception;

	Class<?> getType(String name) throws Exception;

	<T> T getBean(Class<T> requiredType) throws Exception;

	<T> Map<String,T> getBeansOfType(Class<T> type)throws Exception;
}

DefaultBeanFactory

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import java.io.Closeable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class DefaultBeanFactory implements BeanDefinitionRegistry, Beanfactory, Closeable {

	// 存储结构:存beanName和beanDefinition的映射关系
	protected Map<String, BeanDefinition> beanDefintionMap = new ConcurrentHashMap<>(256);

	private Map<String, Object> singletonBeanMap = new ConcurrentHashMap<>(256);

	private Map<Class<?>, Set<String>> typeNameMap = new ConcurrentHashMap<>(256);

	// 存储创建中的对象
	private ThreadLocal<Set<String>> buildingBeansRecordor = new ThreadLocal<>();

	// 提前暴露对象
	private ThreadLocal<Map<String, Object>> earlyExposeBuildingBeans = new ThreadLocal<>();

	@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws Exception {
		Objects.requireNonNull(beanName, "注册bean需要提供beanName");
		Objects.requireNonNull(beanDefinition, "注册bean需要提供beanDefinition");

		// 校验给入的bean是否合法
		if (!beanDefinition.validate()) {
			throw new RuntimeException("名字为[" + beanName + "] 的bean定义不合法:" + beanDefinition);
		}

		// Spring中默认是不可覆盖(抛异常),可通过参数 spring.main.allow-bean-definition-overriding: true 来允许覆盖
		if (this.containsBeanDefinition(beanName)) {
			throw new RuntimeException("名字为[" + beanName + "] 的bean定义已存在:" + this.getBeanDefinition(beanName));
		}

		beanDefintionMap.put(beanName, beanDefinition);
		this.registerTypeNameMap();
	}

	public void registerTypeNameMap() throws Exception {
		for (String name : beanDefintionMap.keySet()) {
			Class<?> type = this.getType(name);
			// 注册本类
			this.registerTypeNameMap(type, name);
			// 注册父类:Spring不支持,我们这里也模拟注释掉,不开放
			// this.registerSuperClassTypeNaemMap(type, name);
			// 注册实现的接口
			this.registerInterfaceTypeNaemMap(type, name);
		}
	}

	private void registerTypeNameMap(Class<?> type, String name) {
		Set<String> beanNames = typeNameMap.get(type);
		if (beanNames == null) {
			beanNames = new HashSet<>();
			typeNameMap.put(type, beanNames);
		}
		beanNames.add(name);
	}

	private void registerSuperClassTypeNaemMap(Class<?> type, String name) {
		Class<?> superclass = type.getSuperclass();
		if (superclass != null && !superclass.equals(Object.class)) {
			// 注册本类
			this.registerTypeNameMap(superclass, name);
			// 注册父类
			this.registerSuperClassTypeNaemMap(superclass, name);
			// 注册实现的接口
			this.registerInterfaceTypeNaemMap(superclass, name);
		}
	}

	private void registerInterfaceTypeNaemMap(Class<?> type, String name) {
		Class<?>[] interfaces = type.getInterfaces();
		for (Class<?> anInterface : interfaces) {
			this.registerTypeNameMap(anInterface, name);
			this.registerInterfaceTypeNaemMap(anInterface, name);
		}
	}

	@Override
	public BeanDefinition getBeanDefinition(String beanName) {
		return beanDefintionMap.get(beanName);
	}

	@Override
	public boolean containsBeanDefinition(String beanName) {
		return beanDefintionMap.containsKey(beanName);
	}

	@Override
	public Object getBean(String name) throws Exception {
		return this.doGetBean(name);
	}

	@Override
	public Class<?> getType(String name) throws Exception {
		BeanDefinition beanDefinition = this.getBeanDefinition(name);
		Class<?> beanClass = beanDefinition.getBeanClass();
		List<?> constructorArgumentValues = beanDefinition.getConstructorArgumentValues();
		if (beanClass != null) {
			// 如果是静态工厂方法,需要获取工厂创建的对象
			if (StringUtils.isNotBlank(beanDefinition.getFactoryMethodName())) {
				return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), this.listConverClassArr(constructorArgumentValues)).getReturnType();
			} else {
				return beanClass;
			}
		} else {
			// 其它情况是工厂方法的处理
			Method factoryMethod = beanDefinition.getFactoryMethod();
			if (factoryMethod != null) {
				return factoryMethod.getReturnType();
			} else {
				beanClass = getType(beanDefinition.getFactoryBeanName());
				return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), this.listConverClassArr(constructorArgumentValues)).getReturnType();
			}
		}
	}

	private Class<?>[] listConverClassArr(List<?> constructorArgumentValues) throws Exception {
		Class<?>[] res = new Class[constructorArgumentValues.size()];
		Class<?> type = null;
		if (constructorArgumentValues.isEmpty()) {
			return res;
		}
		for (int i = 0; i < constructorArgumentValues.size(); i++) {
			Object arg = constructorArgumentValues.get(i);
			if (arg instanceof cn.forlan.aop.beans.BeanReference) {
				cn.forlan.aop.beans.BeanReference beanReference = (cn.forlan.aop.beans.BeanReference) arg;
				if (StringUtils.isNotBlank(beanReference.getBeanName())) {
					type = this.getType(beanReference.getBeanName());
				} else {
					type = beanReference.getType();
				}
			} else {
				type = arg.getClass();
			}
			res[i] = type;
		}
		return res;
	}

	@Override
	public <T> T getBean(Class<T> requiredType) throws Exception {
		Set<String> beanNames = typeNameMap.get(requiredType);
		if (null == beanNames) {
			return null;
		}
		if (beanNames.size() == 1) {
			String beanName = beanNames.iterator().next();
			return (T) this.getBean(beanName);
		} else {
			String primaryBeanName = null;
			for (String beanName : beanNames) {
				BeanDefinition beanDefinition = this.getBeanDefinition(beanName);
				if (beanDefinition != null && beanDefinition.isPrimary()) {
					if (primaryBeanName == null) {
						primaryBeanName = beanName;
					} else {
						throw new RuntimeException(requiredType + "类存在多个Primary,无法确定唯一一个Bean");
					}
				}
			}
			if (primaryBeanName != null) {
				return (T) this.getBean(primaryBeanName);
			} else {
				throw new RuntimeException(requiredType + "类未找到对应的Bean");
			}
		}
	}

	@Override
	public <T> Map<String, T> getBeansOfType(Class<T> type) throws Exception {
		Set<String> beanNames = typeNameMap.get(type);
		if (null == beanNames) {
			return null;
		}
		Map<String, T> nameBeanMap = new HashMap<String, T>();
		for (String beanName : beanNames) {
			nameBeanMap.put(beanName, (T) this.getBean(beanName));
		}
		return nameBeanMap;
	}

	private Object doGetBean(String beanName) throws Exception {
		Objects.requireNonNull(beanName, "beanName不能为空");

		Object instance = singletonBeanMap.get(beanName);
		if (instance != null) {
			return instance;
		}

		instance = this.getFromEarlyExposeBuildingBeans(beanName);
		if (instance != null) { //这是属性依赖时的循环引用,返回提前暴露的实例
			return instance;
		}

		BeanDefinition beanDefinition = this.getBeanDefinition(beanName);
		Objects.requireNonNull(beanDefinition, "beanDefinition不能为空");

		// 检测构造参数循环依赖
		Set<String> buildingBeans = this.buildingBeansRecordor.get();
		if (buildingBeans == null) {
			buildingBeans = new HashSet<>();
			this.buildingBeansRecordor.set(buildingBeans);
		}
		if (buildingBeans.contains(beanName)) {
			throw new Exception(beanName + " 循环依赖!" + buildingBeans);
		}
		// 记录正在创建的Bean
		buildingBeans.add(beanName);

		if (beanDefinition.isSingleton()) {
			synchronized (singletonBeanMap) {
				instance = singletonBeanMap.get(beanName);
				if (instance == null) {
					instance = doCreateInstance(beanName, beanDefinition);
					singletonBeanMap.put(beanName, instance);
				}
			}
		} else {
			instance = doCreateInstance(beanName, beanDefinition);
		}
		// 创建好实例后,移除创建中记录
		buildingBeans.remove(beanName);
		return instance;
	}

	private Object getFromEarlyExposeBuildingBeans(String beanName) {
		Map<String, Object> earlyExposeBuildingBeansMap = earlyExposeBuildingBeans.get();
		return earlyExposeBuildingBeansMap == null ? null : earlyExposeBuildingBeansMap.get(beanName);
	}

	private Object doCreateInstance(String beanName, BeanDefinition bd) throws Exception {
		Class<?> beanClass = bd.getBeanClass();
		Object instance = null;
		if (beanClass != null) {
			if (StringUtils.isBlank(bd.getFactoryMethodName())) {
				// 构造方法来构造对象
				instance = this.createInstanceByConstructor(bd);
			} else {
				// 静态工厂方法
				instance = this.createInstanceByStaticFactoryMethod(bd);
			}
		} else {
			// 工厂bean方式来构造对象
			instance = this.createInstanceByFactoryBean(bd);
		}

		// 赋值前暴露半成品对象
		this.doEarlyExposeBuildingBeans(beanName, instance);

		// 支持属性依赖
		this.setPropertyDIValues(bd, instance);

		// 赋完值移除
		this.removeEarlyExposeBuildingBeans(beanName);

		// 执行初始化方法
		this.doInit(bd, instance);

		return instance;
	}

	private void doEarlyExposeBuildingBeans(String beanName, Object instance) {
		Map<String,Object> earlyExposeBuildingBeansMap = earlyExposeBuildingBeans.get();
		if (earlyExposeBuildingBeansMap == null) {
			earlyExposeBuildingBeansMap = new HashMap<>();
			earlyExposeBuildingBeans.set(earlyExposeBuildingBeansMap);
		}
		earlyExposeBuildingBeansMap.put(beanName, instance);
	}

	private void setPropertyDIValues(BeanDefinition bd, Object instance) throws Exception {
		if (CollectionUtils.isEmpty(bd.getPropertyValues())) {
			return;
		}
		for (PropertyValue pv : bd.getPropertyValues()) {
			if (StringUtils.isBlank(pv.getName())) {
				continue;
			}
			Class<?> clazz = instance.getClass();
			Field p = clazz.getDeclaredField(pv.getName());
			// 允许访问所有,包括private
			p.setAccessible(true);
			// 可能是引用对象,需要获取真正的值
			p.set(instance, this.getOneArgumentRealValue(pv.getValue()));
		}
	}

	private void removeEarlyExposeBuildingBeans(String beanName) {
		earlyExposeBuildingBeans.get().remove(beanName);
	}

	// 构造方法来构造对象:new BeanClass(xxx...)
	private Object createInstanceByConstructor(BeanDefinition bd) throws Exception {
		// 1、获取参数值
		Object[] args = this.getConstructorArgumentValues(bd);
		// 2、确定调用什么构造方法来创建实例
		Constructor constructor = this.determineConstructor(bd, args);
		return constructor.newInstance(args);
	}

	private Object[] getConstructorArgumentValues(BeanDefinition bd) throws Exception {
		List<?> defs = bd.getConstructorArgumentValues();
		if (CollectionUtils.isEmpty(defs)) {
			return null;
		}
		Object[] values = new Object[defs.size()];
		int index = 0;
		for (Object originalValue : defs) {
			values[index++] = getOneArgumentRealValue(originalValue);
		}
		return values;
	}

	private Object getOneArgumentRealValue(Object originalValue) throws Exception {
		//获取真正参数值,主要是处理BeanReference,得到真正的Bean实例
		Object realValue = null;
		if (originalValue == null) {
			return realValue;
		}
		if (originalValue instanceof BeanReference) {
			//  处理bean引用
			BeanReference br = (BeanReference) originalValue;
			if (StringUtils.isNotBlank(br.getBeanName())) {
				realValue = this.getBean(br.getBeanName());
			} else if (br.getType() != null) {
				realValue = this.getBean(br.getType());
			}
		} else if (originalValue instanceof Object[]) {
			// 处理数组中的bean引用
			Object[] objects = (Object[]) originalValue;
			for (int i = 0; i < objects.length; i++) {
				if (objects[i] instanceof BeanReference) {
					objects[i] = getOneArgumentRealValue(objects[i]);
				}
			}
			realValue = objects;
		} else if (originalValue instanceof Collection) {
			// 处理集合中的bean引用
			if (originalValue instanceof Set) {
				Set set = (Set) originalValue;
				Iterator iterator = set.iterator();
				Set newSet = new HashSet();
				while (iterator.hasNext()) {
					Object next = iterator.next();
					if (next instanceof BeanReference) {
						iterator.remove();
						// set.add(getOneArgumentRealValue(next));
						newSet.add(getOneArgumentRealValue(next));
					}
				}
				set.addAll(newSet);
				realValue = set;
			} else if (originalValue instanceof List) {
				List list = (List) originalValue;
				for (int i = 0; i < list.size(); i++) {
					if (list.get(i) instanceof BeanReference) {
						list.set(i, getOneArgumentRealValue(list.get(i)));
					}
				}
				realValue = list;
			} else {
				realValue = originalValue;
			}
		} /*else if (originalValue instanceof Map) {
			// TODO 处理Map中的bean引用
		} */ else {
			realValue = originalValue;
		}
		return realValue;
	}

	private Constructor<?> determineConstructor(BeanDefinition bd, Object[] args) throws Exception {
		// 无参数,就调用无参构造方法即可
		if (args == null) {
			return bd.getBeanClass().getConstructor(null);
		}
		Constructor<?> constructor = null;
		// 对于原型bean,从第二次开始获取bean实例时,可直接获得第一次缓存的构造方法。
		constructor = bd.getConstructor();
		if (constructor != null) {
			return constructor;
		}

		// 有参数,先精确匹配,匹配不到,再模糊匹配
		// 1、精确匹配
		Class<?>[] parameterTypes = new Class[args.length];
		for (int i = 0; i < args.length; i++) {
			parameterTypes[i] = args[i].getClass();
		}
		try {
			constructor = bd.getBeanClass().getConstructor(parameterTypes);
		} catch (Exception e) {
			// 这里可能找不到会报错,不用处理
		}

		// 2、模糊匹配
		if (constructor == null) {
			Constructor<?>[] constructors = bd.getBeanClass().getConstructors();
			outer:
			for (Constructor<?> constructorTemp : constructors) {
				Class<?>[] tempParameterTypes = constructorTemp.getParameterTypes();
				// 参数列表个数一样
				if (tempParameterTypes.length == args.length) {
					for (int i = 0; i < tempParameterTypes.length; i++) {
						// 判断tempParameterTypes是否是其父类或者相同类
						if (!tempParameterTypes[i].isAssignableFrom(args[i].getClass())) {
							// 参数类型不一样,跳到下一个构造方法
							continue outer;
						}
					}
					constructor = constructorTemp;
					break outer;
				}
			}
		}

		// 3、还没找到,抛出异常提示
		if (constructor == null) {
			throw new Exception(bd + "不存在对应的构造方法");
		}

		if (bd.isPrototype()) {
			// 对于原型bean,可以缓存找到的构造方法,方便下次构造实例对象
			bd.setConstructor(constructor);
		}
		return constructor;
	}

	// 静态工厂方法:BeanClass.factoryMethodName(xxx...)
	private Object createInstanceByStaticFactoryMethod(BeanDefinition bd) throws Exception {
		// 1、获取参数值
		Object[] args = this.getConstructorArgumentValues(bd);
		// 2、确定调用什么方法来执行获取示例
		Class<?> beanClass = bd.getBeanClass();
		Method m = this.determineMethod(bd, beanClass, args);
		return m.invoke(beanClass, args);
	}

	private Method determineMethod(BeanDefinition beanDefinition, Class<?> beanClass, Object[] args) throws Exception {
		Method targetMethod = null;

		// 对于原型bean,从第二次开始获取方法时,可直接获得第一次缓存的方法
		targetMethod = beanDefinition.getFactoryMethod();
		if (targetMethod != null) {
			return targetMethod;
		}

		// 1、精确匹配
		Class<?>[] parameterTypes = new Class[args.length];
		for (int i = 0; i < args.length; i++) {
			parameterTypes[i] = args[i].getClass();
		}
		String factoryMethodName = beanDefinition.getFactoryMethodName();
		try {
			targetMethod = beanClass.getMethod(factoryMethodName, parameterTypes);
		} catch (Exception e) {
			// 这里可能找不到会报错,不用处理,走后续的模糊匹配即可
		}


		// 2、模糊匹配
		if (targetMethod == null) {
			outer:
			for (Method method : beanClass.getMethods()) {
				if (Objects.equals(factoryMethodName, method.getName())) {
					continue;
				}
				Class<?>[] tempparameterTypes = method.getParameterTypes();
				if (parameterTypes.length == args.length) {
					for (int i = 0; i < parameterTypes.length; i++) {
						if (!tempparameterTypes[i].getClass().isAssignableFrom(args[i].getClass())) {
							continue outer;
						}
						targetMethod = method;
						break outer;
					}
				}
			}
		}

		// 3、还没找到,抛出异常提示
		if (targetMethod == null) {
			throw new Exception(beanDefinition + "不存在对应的方法");
		}

		// 对于原型bean,可以缓存找到的方法,方便下次构造实例对象
		if (beanDefinition.isPrototype()) {
			beanDefinition.setFactoryMethod(targetMethod);
		}

		return targetMethod;
	}

	// 工厂bean方式来构造对象:new FactoryBeanName().factoryMethodName(xxx...)
	private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {
		// 1、获取工厂bean
		Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
		Class<?> factoryBeanClass = factoryBean.getClass();
		// 2、获取参数值
		Object[] args = this.getConstructorArgumentValues(bd);
		// 3、确定调用什么方法来执行获取示例
		Method m = this.determineMethod(bd, factoryBeanClass, args);
		return m.invoke(factoryBean, args);
	}

	private void doInit(BeanDefinition bd, Object instance) throws Exception {
		// 执行初始化方法
		if (StringUtils.isNotBlank(bd.getInitMethodName())) {
			Method m = instance.getClass().getMethod(bd.getInitMethodName(), null);
			m.invoke(instance, null);
		}
	}

	@Override
	public void close() {
		for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : beanDefintionMap.entrySet()) {
			String beanName = beanDefinitionEntry.getKey();
			BeanDefinition beanDefinition = beanDefinitionEntry.getValue();
			if (beanDefinition.isSingleton() && singletonBeanMap.containsKey(beanName)) {
				Object instance = this.singletonBeanMap.get(beanName);
				try {
					Method m = instance.getClass().getMethod(beanDefinition.getDestroyMethodName(), null);
					m.invoke(instance, null);
				} catch (Exception e) {
					log.error("执行名字为[" + beanName + "] 的bean销毁方法异常", e);
				}
			}
		}
	}
}

PreBuildBeanFactory

import lombok.extern.slf4j.Slf4j;
import java.util.Map;

@Slf4j
public class PreBuildBeanFactory extends DefaultBeanFactory{
	public void preInstantiateSingletons() throws Exception {
		synchronized (this.beanDefintionMap) {
			for (Map.Entry<String, BeanDefinition> entry : this.beanDefintionMap.entrySet()) {
				String name = entry.getKey();
				BeanDefinition beanDefinition = entry.getValue();
				if (beanDefinition.isSingleton()) {
					this.getBean(name);
					if (log.isDebugEnabled()) {
						log.debug("preInstantiate: name=" + name + " " + beanDefinition);
					}
				}
			}
		}
	}
}
  • 14
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Forlan

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值