Spring源码:手写SpringIOC

news2025/1/15 21:49:16

文章目录

  • 一、分析
  • 二、实现
    • 1、版本1:实现Bean注入IOC容器,并从容器中获取
      • 1)定义BeanDefinition
      • 2)定义BeanDefinition实现类
      • 3)定义BeanDefinitionRegistry
      • 4)定义Beanfactory
      • 5)定义默认Beanfactory实现类
    • 2、版本2:新增工厂关闭方法和支持单例bean
      • 额外扩展:实现一个预构建BeanFactory,可以在系统启动时,提前初始化
    • 3、版本3:支持获取指定名字的类型
    • 4、版本4:获取指定类型的所有bean以及唯一bean
    • 5、版本5:支持Bean别名
  • 三、最终完整版本
    • BeanDefinition
    • GenericBeanDefinition
    • BeanDefinitionRegistry
    • Beanfactory
    • DefaultBeanFactory
    • PreBuildBeanFactory

一、分析

IOC是Inversion of Control(控制反转)的缩写。它是一种软件设计原则,用于解耦组件之间的依赖关系。

也就是依赖对象的获取被反转了,从原来我们自己创建对象-》从IOC容器中获取,由它来管理。

这样的好处是什么?

代码更加简洁,不用自己去new对象
面向接口编程:解耦,易扩展,替换实现类;方便进行AOP编程

那么,你有啥思路?

其实可以这么理解,IOC容器=Bean工厂,Beanfactory会对外提供bean实例,所以需要提供getBean()方法;那么你要什么样的Bean,得描述告诉Bean工厂吧,所以需要一个Bean定义信息BeanDefinition,告诉它应该创建什么对象;我们定义的这些BeanDefinition存在哪?就需要一个注册器BeanDefinitionRegistry去维护这些信息

二、实现

1、版本1:实现Bean注入IOC容器,并从容器中获取

1)定义BeanDefinition

描述我们的bean是要单例还是多例,是通过什么去创建(直接new,还是通过工厂类创建),初始化以及销毁方法

import com.baomidou.mybatisplus.core.toolkit.StringUtils;

/**
 * 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;
    }

}

2)定义BeanDefinition实现类

定义一个通用实现类,实现BeanDefinition接口,对值的设置和获取

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;

	@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;
	}
}

3)定义BeanDefinitionRegistry

public interface BeanDefinitionRegistry {

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

	BeanDefinition getBeanDefinition(String beanName);

	boolean containsBeanDefinition(String beanName);
}

4)定义Beanfactory

提供getBean方法,方便外部获取bean

public interface Beanfactory {

	Object getBean(String name) throws Exception;
}

5)定义默认Beanfactory实现类

实现BeanDefinitionRegistry和Beanfactory 接口,定义一个存储存储结构,存beanName和beanDefinition的映射关系;重写registerBeanDefinition和getBean等方法,定义了三种创建对象的方式:

  • 直接new:new BeanClass
  • 工厂静态方法:BeanClass.factoryMethodName()
  • 工厂bean对象调用方法:new FactoryBeanName().factoryMethodName()
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class DefaultBeanFactory implements BeanDefinitionRegistry, Beanfactory {

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

	@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);
	}

	@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);
	}

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

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

		Object instance = doCreateInstance(bd);
		return instance;
	}

	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.doInit(bd, instance);

		return instance;
	}

	// 构造方法来构造对象:new BeanClass()
	private Object createInstanceByConstructor(BeanDefinition bd) throws Exception {
		try {
			Class<?> beanClass = bd.getBeanClass();
			return beanClass.newInstance();
		} catch (SecurityException e) {
			log.error("创建bean的实例异常,beanDefinition:" + bd, e);
			throw e;
		}
	}

	// 静态工厂方法:BeanClass.factoryMethodName()
	private Object createInstanceByStaticFactoryMethod(BeanDefinition bd) throws Exception {
		Class<?> beanClass = bd.getBeanClass();
		Method m = beanClass.getMethod(bd.getFactoryMethodName(), null);
		return m.invoke(beanClass, null);
	}

	// 工厂bean方式来构造对象:new FactoryBeanName().factoryMethodName()
	private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {
		Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
		Class<?> factoryBeanClass = factoryBean.getClass();
		Method m = factoryBeanClass.getMethod(bd.getFactoryMethodName(), null);
		return m.invoke(factoryBean, null);
	}

	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);
		}
	}
}

2、版本2:新增工厂关闭方法和支持单例bean

主要调整DefaultBeanFactory,实现了Closeable,重写了close方法,只针对单例Bean做了销毁处理,原型不用去销毁
,不知道会创建多少个对象,也得不到这些对象,不用去管,调整doGetBean方法支持单例模式。

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import java.io.Closeable;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;


@Slf4j
public class DefaultBeanFactory implements BeanDefinitionRegistry, Beanfactory, Closeable {
    
    // 单例存储结构:存beanName和对应实例的映射关系
	private Map<String, Object> singletonBeanMap = new ConcurrentHashMap<>(256);

	// 省去其它代码...
	
	private Object doGetBean(String beanName) throws Exception {
		Objects.requireNonNull(beanName, "beanName不能为空");

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

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

		if (beanDefinition.isSingleton()) {
			synchronized (singletonBeanMap) {
				instance = singletonBeanMap.get(beanName);
				if (instance == null) {
					instance = doCreateInstance(beanDefinition);
					singletonBeanMap.put(beanName, instance);
				}
			}

		} else {
			instance = doCreateInstance(beanDefinition);
		}
		return instance;
	}

	@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);
				}
			}
		}
	}
}

额外扩展:实现一个预构建BeanFactory,可以在系统启动时,提前初始化

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);
					}
				}
			}
		}
	}
}

3、版本3:支持获取指定名字的类型

主要调整Beanfactory和DefaultBeanFactory,Beanfactory新增一个getType方法,让子类去实现

public interface Beanfactory {
	Class<?> getType(String name) throws Exception;
}

重写getType方法

@Slf4j
public class DefaultBeanFactory implements BeanDefinitionRegistry, Beanfactory, Closeable {
	@Override
	public Class<?> getType(String name) throws Exception {
		BeanDefinition beanDefinition = this.getBeanDefinition(name);
		Class<?> beanClass = beanDefinition.getBeanClass();
		if (beanClass != null) {
			// 如果是静态工厂方法,需要获取工厂创建的对象
			if (StringUtils.isNotBlank(beanDefinition.getFactoryMethodName())) {
				return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), null).getReturnType();
			} else {
				return beanClass;
			}
		} else {
			// 其它情况是工厂方法的处理
			beanClass = getType(beanDefinition.getFactoryBeanName());
			return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), null).getReturnType();
		}
	}
	
	@Override
	public BeanDefinition getBeanDefinition(String beanName) {
		return beanDefintionMap.get(beanName);
	}
}

4、版本4:获取指定类型的所有bean以及唯一bean

一个type可能对应多个name,使用的存储结构如下:

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

调整DefaultBeanFactory的registerBeanDefinition,新增registerTypeNameMap方法,实现映射类型和beanName集合,支持当前类,父类,以及实现的接口,在Spring中,当你注入一个子类时,它会自动注入该子类实现的接口,而不会自动注入其继承的父类。所以下面实现的registerSuperClassTypeNaemMap,是注入其继承的父类,可以选择不要。

@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);
	registerTypeNameMap();
}

	public void registerTypeNameMap() throws Exception {
		for (String name : beanDefintionMap.keySet()) {
			Class<?> type = this.getType(name);
			// 注册本类
			this.registerTypeNameMap(type, name);
			// 注册父类
			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);
	}
}

Beanfactory新增两个方法如下:

public interface Beanfactory {

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

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

DefaultBeanFactory 实现如下:

@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;
}

5、版本5:支持Bean别名

待实现
在这里插入图片描述

三、最终完整版本

在这里插入图片描述

BeanDefinition

import com.baomidou.mybatisplus.core.toolkit.StringUtils;

/**
 * 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;
    }

}

GenericBeanDefinition

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;

	@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;
	}
}

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 java.io.Closeable;
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);

	@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);
		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();
		if (beanClass != null) {
			// 如果是静态工厂方法,需要获取工厂创建的对象
			if (StringUtils.isNotBlank(beanDefinition.getFactoryMethodName())) {
				return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), null).getReturnType();
			} else {
				return beanClass;
			}
		} else {
			// 其它情况是工厂方法的处理
			beanClass = getType(beanDefinition.getFactoryBeanName());
			return beanClass.getDeclaredMethod(beanDefinition.getFactoryMethodName(), null).getReturnType();
		}
	}

	@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;
		}

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

		if (beanDefinition.isSingleton()) {
			synchronized (singletonBeanMap) {
				instance = singletonBeanMap.get(beanName);
				if (instance == null) {
					instance = doCreateInstance(beanDefinition);
					singletonBeanMap.put(beanName, instance);
				}
			}

		} else {
			instance = doCreateInstance(beanDefinition);
		}
		return instance;
	}

	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.doInit(bd, instance);

		return instance;
	}

	// 构造方法来构造对象:new BeanClass()
	private Object createInstanceByConstructor(BeanDefinition bd) throws Exception {
		try {
			Class<?> beanClass = bd.getBeanClass();
			return beanClass.newInstance();
		} catch (SecurityException e) {
			log.error("创建bean的实例异常,beanDefinition:" + bd, e);
			throw e;
		}
	}

	// 静态工厂方法:BeanClass.factoryMethodName()
	private Object createInstanceByStaticFactoryMethod(BeanDefinition bd) throws Exception {
		Class<?> beanClass = bd.getBeanClass();
		Method m = beanClass.getMethod(bd.getFactoryMethodName(), null);
		return m.invoke(beanClass, null);
	}

	// 工厂bean方式来构造对象:new FactoryBeanName().factoryMethodName()
	private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {
		Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
		Class<?> factoryBeanClass = factoryBean.getClass();
		Method m = factoryBeanClass.getMethod(bd.getFactoryMethodName(), null);
		return m.invoke(factoryBean, null);
	}

	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);
					}
				}
			}
		}
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1459018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学会Requests库,就学会了Python接口自动化

在 Python 中进行网络请求是日常开发中的一个常见任务&#xff0c;而 requests 库是处理这类任务的一种强大工 具。requests 提供了简单而灵活的接口&#xff0c;使得发送 HTTP 请求和处理响应变得非常容易。在这篇文章中&#xff0c;我们将深入研究如何使用 requests 库执行各…

grid新建主从一对多

目录 总结一、步骤前端1.第一步-编写tabs的modelBody2.第二步编辑表扩展js 后端--重写表的add和Update方法1.第一步 总结 编写tabs的modelBody后编辑表扩展js在重写后端partial的Service 一、步骤 前端 1.第一步-编写tabs的modelBody 复制下面代码该改的改 <template&…

Golang for 循环

从基础知识到高级技术、并发和通道 Go&#xff08;Golang&#xff09;编程语言中的“for”循环是一个基本而多功能的结构&#xff0c;用于迭代集合、重复执行代码块以及管理循环控制流。Golang的“for”循环语法简洁却强大&#xff0c;为处理多样的循环场景提供了一系列能力。无…

【2024软件测试面试必会技能】adb命令操作

前言&#xff1a; adb的全称为(Android Debug Bridge&#xff09;就是调试桥的作用。Adb 命令存放在 SDK 的Tools文件夹下&#xff0c;又称为手机和电脑连接的桥梁命令。 借助这个工具&#xff0c;我们可以管理设备或手机模拟器的状态。还可以进行以下的操作&#xff1a; 快…

计算机功能简介:EC, NVMe, SCSI/ISCSI与块存储接口 RBD,NUMA

一 EC是指Embedded Controller 主要应用于移动计算机系统和嵌入式计算机系统中&#xff0c;为此类计算机提供系统管理功能。EC的主要功能是控制计算机主板上电时序、管理电池充电和放电&#xff0c;提供键盘矩阵接口、智能风扇接口、串口、GPIO、PS/2等常规IO功能&#xff0c;…

C#分部类的应用:记录学生信息

目录 一、分部类及其用途 二、实例 再发一个分部类的应用&#xff0c;巩固一下。 一、分部类及其用途 C#中的部分类也被称为分部类。 C#中的部分类是一种将类的定义分成多个部分&#xff0c;每个部分都位于自己的文件中&#xff0c;然后在编译时合并在一起的机制。 部分类…

SNAT与DNAT公私网地址转换

前言 SNAT和DNAT是两种重要的网络地址转换技术&#xff0c;它们允许内部网络中的多个主机共享单个公共IP地址&#xff0c;或者将公共IP地址映射到内部网络中的特定主机。这些技术在构建企业级网络和互联网应用程序时非常重要&#xff0c;因为它们可以帮助保护内部网络安全&…

75.SpringMVC的拦截器和过滤器有什么区别?执行顺序?

75.SpringMVC的拦截器和过滤器有什么区别&#xff1f;执行顺序&#xff1f; 区别 拦截器不依赖与servlet容器&#xff0c;过滤器依赖与servlet容器。拦截器只能对action请求(DispatcherServlet 映射的请求)起作用&#xff0c;而过滤器则可以对几乎所有的请求起作用。拦截器可…

阿里云服务器操作系统有哪些?如何选择?

阿里云服务器镜像怎么选择&#xff1f;云服务器操作系统镜像分为Linux和Windows两大类&#xff0c;Linux可以选择Alibaba Cloud Linux&#xff0c;Windows可以选择Windows Server 2022数据中心版64位中文版&#xff0c;阿里云服务器网aliyunfuwuqi.com来详细说下阿里云服务器操…

深入理解java虚拟机---自动内存管理

2.2 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途&#xff0c;以及创建和销毁的时间&#xff0c;有的区域随着虚拟机进程的启动而一直存在&#xff0c;有些区域则是依赖用户线程的启动和结束而建立和销…

[word] word定时自动保存功能的作用是什么 #知识分享#学习方法#媒体

word定时自动保存功能的作用是什么 word定时自动保存功能的作用是什么 这是word提供的一个保护用户文档的功能&#xff0c;一般情况下是为了预防在未知原因的情况下&#xff0c;用户电脑关闭&#xff0c;或者不小关掉Word&#xff0c;导致正在使用的文档丢失&#xff0c;给用户…

华清远见作业第三十九天——Qt(第一天)

思维导图&#xff1a; 登录界面&#xff1a; 代码&#xff1a; #include "mainwindow.h" #include<QToolBar> #include<QPushButton> MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {this->resize(600,400);this->setFixedSize…

Vue+SpringBoot打造生活废品回收系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…

C++拷贝构造函数与赋值运算符重载

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、拷贝构造函数 1.概念 在现实生活中&#xff0c;可能存在一个与你一样的自己&#xff0c;我们称其为双胞胎。 那在创…

day1:组件的代码实现

思维导图 设计一个登录界面 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {this->setWindowFlag(Qt::FramelessWindowHint);this->resize(700,550);this->setWindowIcon(QIcon("D:/学校工作/截图/b1.jpg"));/***…

经验分享——Jmeter压力测试工具安装,使用

之前测试都是简单的写个线程模拟请求测试&#xff0c;后面经同事推荐这款压力测试工具。真的很好用&#xff0c;使用过几次了&#xff0c;于是把自己使用过程中遇到的问题&#xff0c;以及相关配置分享出来。希望给需要用到的人一些帮助。 一 下载 首选下载这款工具&#xff…

【蜂窝物联】公寓WiFi全覆盖解决方案

项目背景 随着移动设备越来越普及&#xff0c;人们对于网络的需求愈发强烈&#xff0c;WIFI覆盖也逐渐进入网民的视野中。部署无线网络不仅能提高出租屋服务水平及竞争力&#xff0c;同时也可以为出租屋提高收入&#xff0c;蜂窝为出租屋房东提供一套完整的解决方案。 01 需求…

SICTF Round#3 wp web

web hacker sql无列名注入&#xff1b; 提示查询username参数&#xff0c;flag在flag表中&#xff1b; 传参测试发现&#xff0c;union select 可用&#xff0c;空格被过滤可以使用/**/代替 &#xff0c;or也被过滤了且无法大小写、双写等绕过&#xff0c;导致无法查询flag表…

【开源】SpringBoot框架开发高校宿舍调配管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统展示四、核心代码4.1 查询单条个人习惯4.2 查询我的室友4.3 查询宿舍4.4 查询指定性别全部宿舍4.5 初次分配宿舍 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的…

java8的 lambda表达式到stream API总结备忘

文章目录 1. Lambda 表达式为什么使用 Lambda 表达式从匿名类到 Lambda 的转换Lambda 表达式语法语法格式一&#xff1a;无参&#xff0c;无返回值&#xff0c;Lambda 体只需一条语句语法格式二&#xff1a;Lambda 需要一个参数语法格式三&#xff1a;Lambda 只需要一个参数时&…