Spring源码分析

在这里插入图片描述

Spring源码 -IOC

IOC是什么

 IoC:Inversion of Control 控制反转,简单理解就是:依赖对象的获得被反转了。
在这里插入图片描述
IoC带来的好处:

  1. 代码更加简洁,不需要去new 要使用的对象了
  2. 面向接口编程,使用者与具体类,解耦,易扩展、替换实现者
  3. 可以方便进行AOP编程
    在这里插入图片描述
    emsp; IoC容器的工作:负责创建,管理类实例,向使用者提供实例。
    在这里插入图片描述

BeanFactory和BeanDefinition介绍

BeanFactory

IOC容器也称为Bean工厂
bean 组件,也就是类的对象!!!
在这里插入图片描述

Bean工厂的作用

  首先Bean工厂的作用上面也分析了就是创建,管理Bean,并且需要对外提供Bean的实例。
在这里插入图片描述
 首先Bean工厂应该要对外提供获取bean实例的方法,所以需要定义一个getBean()方法。同时工厂需要知道生产的bean的类型,所以getBean()方法需要接受对应的参数,同时返回类型这块也可能有多个类型,就用Object来表示。这样Bean工厂的定义就出来了。
在这里插入图片描述
Bean工厂创建对象过程
在这里插入图片描述

Bean的定义

Bean定义的作用

  肯定是告诉Bean工厂应该如何来创建某类的Bean实例

获取实例的方式

在这里插入图片描述

BeanDefinition给Bean工厂的信息

在这里插入图片描述
这就是BeanDefinition的基本功能了
在这里插入图片描述

BeanDefinitionRegistry

在这里插入图片描述
BeanDefinitionRegistry 应该具备的功能,其实也简单就两个:

  1. 注册BeanDefinition
  2. 获取BeanDefinition

  同时为了保证能够区分每个BeanDefinition的定义信息,我们得给每一个Bean定义一个唯一的名称。
在这里插入图片描述
具体实现代码:

public interface BeanDefinitionRegistry {
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionRegistException;
	BeanDefinition getBeanDefinition(String beanName);
	boolean containsBeanDefinition(String beanName);

}

BeanFactory实现

spring销毁原型(priority类型)的bean

spring并不会销毁原型(priority类型)的bean

在这里插入图片描述
BeanFactory的功能实现了。先来实现一个最基础的默认的Bean工厂:DefaultBeanFactory。需要DefaultBeanFactory实现如下的5个功能

  1. 实现Bean定义信息的注册
public interface BeanFactory {

	Object getBean(String name) throws Exception;

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

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

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

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

    String SCOPE_SINGLETION = "singleton";

    String SCOPE_PROTOTYPE = "prototype";

    /**
     * 类
     */
    Class<?> getBeanClass();

    /**
     * Scope
     */
    String getScope();

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

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

    /**
     * 工厂bean名
     */
    String getFactoryBeanName();

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

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

    /**
     * 销毁方法
     */
    String getDestroyMethodName();

    boolean isPrimary();

    /**
     * 校验bean定义的合法性
     */
    default boolean validate() {
        // 没定义class,工厂bean或工厂方法没指定,则不合法。
        if (this.getBeanClass() == null) {
            if (StringUtils.isBlank(getFactoryBeanName()) || StringUtils.isBlank(getFactoryMethodName())) {
                return false;
            }
        }

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

/**
 * BeanDefinition默认实现
 */
public class GenericBeanDefinition implements BeanDefinition {

	private Class<?> beanClass;

	private String scope = SCOPE_SINGLETION;

	private String factoryBeanName;

	private String factoryMethodName;

	private String initMethodName;

	private String destroyMethodName;

	private boolean primary;

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

	public void setScope(String scope) {
		if (StringUtils.isNotBlank(scope)) {
			this.scope = scope;
		}
	}

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

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

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

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

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

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

	@Override
	public boolean isSingleton() {
		return SCOPE_SINGLETION.equals(this.scope);
	}

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

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

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

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

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

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

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

	@Override
	public String toString() {
		return "GenericBeanDefinition [beanClass=" + beanClass + ", scope=" + scope + ", factoryBeanName="
				+ factoryBeanName + ", factoryMethodName=" + factoryMethodName + ", initMethodName=" + initMethodName
				+ ", destroyMethodName=" + destroyMethodName + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((beanClass == null) ? 0 : beanClass.hashCode());
		result = prime * result + ((destroyMethodName == null) ? 0 : destroyMethodName.hashCode());
		result = prime * result + ((factoryBeanName == null) ? 0 : factoryBeanName.hashCode());
		result = prime * result + ((factoryMethodName == null) ? 0 : factoryMethodName.hashCode());
		result = prime * result + ((initMethodName == null) ? 0 : initMethodName.hashCode());
		result = prime * result + ((scope == null) ? 0 : scope.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		GenericBeanDefinition other = (GenericBeanDefinition) obj;
		if (beanClass == null) {
			if (other.beanClass != null)
				return false;
		} else if (!beanClass.equals(other.beanClass))
			return false;
		if (destroyMethodName == null) {
			if (other.destroyMethodName != null)
				return false;
		} else if (!destroyMethodName.equals(other.destroyMethodName))
			return false;
		if (factoryBeanName == null) {
			if (other.factoryBeanName != null)
				return false;
		} else if (!factoryBeanName.equals(other.factoryBeanName))
			return false;
		if (factoryMethodName == null) {
			if (other.factoryMethodName != null)
				return false;
		} else if (!factoryMethodName.equals(other.factoryMethodName))
			return false;
		if (initMethodName == null) {
			if (other.initMethodName != null)
				return false;
		} else if (!initMethodName.equals(other.initMethodName))
			return false;
		if (scope == null) {
			if (other.scope != null)
				return false;
		} else if (!scope.equals(other.scope))
			return false;
		return true;
	}

}

注册bean的

public interface BeanDefinitionRegistry {

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

	BeanDefinition getBeanDefinition(String beanName);

	boolean containsBeanDefinition(String beanName);

}
//自定义bean异常
public class BeanDefinitionRegistException extends Exception {

	private static final long serialVersionUID = 6056374114834139330L;

	public BeanDefinitionRegistException(String mess) {
		super(mess);
	}

	public BeanDefinitionRegistException(String mess, Throwable e) {
		super(mess, e);
	}
}
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
    
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionRegistException {
        Objects.requireNonNull(beanName, "注册bean需要给入beanName");
        Objects.requireNonNull(beanDefinition, "注册bean需要给入beanDefinition");

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

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

        this.beanDefintionMap.put(beanName, beanDefinition);
    }
	
	@Override
    public boolean containsBeanDefinition(String beanName) {
        return this.beanDefintionMap.containsKey(beanName);
    }
    
}
  1. 实现Bean工厂定义的getBean方法
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
	protected Map<String, BeanDefinition> beanDefintionMap = new ConcurrentHashMap<>(256);

	private Map<String, Object> singletonBeanMap = new ConcurrentHashMap<>(256);
	@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<?> type = bd.getBeanClass();
        Object instance = null;
        if (type != 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;
    }
	
	// 构造方法来构造对象
    private Object createInstanceByConstructor(BeanDefinition bd)
            throws InstantiationException, IllegalAccessException {
        try {
            return bd.getBeanClass().newInstance();
        } catch (SecurityException e1) {
            log.error("创建bean的实例异常,beanDefinition:" + bd, e1);
            throw e1;
        }
    }

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

    // 工厂bean方式来构造对象
    private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {
        Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
        Method m = factoryBean.getClass().getMethod(bd.getFactoryMethodName(), null);
        return m.invoke(factoryBean, null);
    }
}
  1. 实现初始化方法的执行
	/**
     * 执行初始化方法
     *
     * @param bd
     * @param instance
     * @throws Exception
     */
    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);
        }
    }
  1. 实现单例的要求
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
	protected Map<String, BeanDefinition> beanDefintionMap = new ConcurrentHashMap<>(256);

	private Map<String, Object> singletonBeanMap = new ConcurrentHashMap<>(256);
	
	//...其他方法省略
	@Override
    public Object getBean(String name) throws Exception {
        return this.doGetBean(name);
    }
	private Object doGetBean(String beanName) throws Exception {
        Objects.requireNonNull(beanName, "beanName不能为空");
		/*单例如何实现?
			单例如何存储?
			如何保证单例?
		*/
		Object instance = singletonBeanMap.get(beanName);
		if (instance != null) {
			return instance;
		}
		BeanDefinition bd = this.getBeanDefinition(beanName);
		Objects.requireNonNull(bd, "beanDefinition不能为空");

		//前面已经判断过   == null
		if(bd.isSingleton()) { //如果是单例   DCL
			synchronized (this.singletonBeanMap) { //加锁
				instance = this.singletonBeanMap.get(beanName);
				if(instance == null){//第二次检查
					instance = doCreateInstance(bd);
					this.singletonBeanMap.put(beanName,instance);
				}
			}   // volatile  可见性
		}
		else {
			instance = doCreateInstance(bd);
		}
		return instance;
    }
    
	@Override
    public BeanDefinition getBeanDefinition(String beanName) {
        return this.beanDefintionMap.get(beanName);
    }
  1. 实现容器关闭是执行单例的销毁操作
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
	@Override
	public void close() throws IOException {
		// 执行单例实例的销毁方法
		for (Entry<String, BeanDefinition> e : this.beanDefintionMap.entrySet()) {
			String beanName = e.getKey();
			BeanDefinition bd = e.getValue();

			if (bd.isSingleton() && StringUtils.isNotBlank(bd.getDestroyMethodName())) {
				Object instance = this.singletonBeanMap.get(beanName);
				try {
					Method m = instance.getClass().getMethod(bd.getDestroyMethodName(), null);
					m.invoke(instance, null);
				} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
						| InvocationTargetException e1) {
					log.error("执行bean[" + beanName + "] " + bd + " 的 销毁方法异常!", e1);
				}
			}
		}

		//疑问:原型Bean如果指定了销毁方法,怎么办?
		//spring并不会缓存原型bean,所以不存在销毁这一说
	}
}

在这里插入图片描述

单例bean,提前实例化

在这里插入图片描述

public class PreBuildBeanFactory extends DefaultBeanFactory {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PreBuildBeanFactory.class);

    public void preInstantiateSingletons() throws Exception {
        synchronized (this.beanDefintionMap) {
            for (Map.Entry<String, BeanDefinition> entry : this.beanDefintionMap.entrySet()) {
                String name = entry.getKey();
                BeanDefinition bd = entry.getValue();
                if (bd.isSingleton()) {
                    this.getBean(name);
                    if (log.isDebugEnabled()) {
                        log.debug("preInstantiate: name=" + name + " " + bd);
                    }
                }
            }
        }
    }
}

Type类型的增强

 上面实现的是根据 bean的 name来获取Bean实例,还希望能扩展通过 Type来获取实例对象。这时对应的接口为:
在这里插入图片描述
  也就是需要实现根据Type找到Bean对象的功能。正常的实例逻辑为:
在这里插入图片描述

public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
	@Override
	public <T> T getBean(Class<T> type) throws Exception {
		/*
		逻辑:
		1 获得其对应的所有的BeanDefinition
		2 如果只有一个,直接获取bean实例返回,否则
		3 遍历找出Primary的
		4 如果primary没有,或大于1个,抛出异常
		5 返回Primary的实例
		 */
		Set<String> names = this.typeMap.get(type);
		if(names != null) {
			if(names.size() == 1){
				return (T)this.getBean(names.iterator().next());
			}
			else {
				//找Primary
				BeanDefinition bd = null;
				String primaryName = null;
				StringBuilder nameStrings = new StringBuilder();
				for(String name : names){
					bd = this.getBeanDefinition(name);
					if(bd != null && bd.isPrimary()) {
						if(primaryName != null){
							String mess = type + " 类型的Bean存储多个Primary[" + primaryName + "," + name + "]";
							log.error(mess);
							throw new Exception(mess);
						}
						else {
							primaryName = name;
						}
					}
					nameStrings.append(" " + name);
				}

				if(primaryName != null){
					return (T)this.getBean(primaryName);
				}
				else {
					String mess = type + " 类型的Bean存在多个[" + nameStrings + "] 但无法确定Primary";
					log.error(mess);
					throw new Exception(mess);
				}
			}
		}
		return null;
	}
}

IoC容器-核心部分类图

在这里插入图片描述
总结:应用设计的原则:

  1. 抽象,行为抽象分类处理(接口)
  2. 继承,扩展功能
  3. 面向接口编程
  4. 单一职责原则

DefaultBeanFactory完整代码

public class DefaultBeanFactory  implements BeanFactory, BeanDefinitionRegistry, Closeable {
	private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultBeanFactory.class);

	protected Map<String, BeanDefinition> beanDefintionMap = new ConcurrentHashMap<>(256);

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

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

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

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

		if (this.containsBeanDefinition(beanName)) {
			throw new BeanDefinitionRegistException(
					"名字为[" + beanName + "] 的bean定义已存在:" + this.getBeanDefinition(beanName));
		}

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

	public void registerTypeMap() throws Exception{
		//1 得到 type -- name 映射关系 准备工作  在所有的Bean定义信息都注册完成后执行
		for(String name : this.beanDefintionMap.keySet()){
			Class<?> type = this.getType(name);
			//映射本类
			this.registerTypeMap(name,type);

			//父类
			this.registerSuperClassTypeMap(name,type);
			//接口
			this.registerInterfaceTypeMap(name,type);
		}

	}

	private void registerInterfaceTypeMap(String name, Class<?> type) {
		Class<?>[] interfaces = type.getInterfaces();
		if (interfaces.length > 0){
			for(Class<?> interf : interfaces) {
				this.registerTypeMap(name, interf);
				//递归找父接口
				this.registerInterfaceTypeMap(name,interf);
			}
		}
	}

	private void registerSuperClassTypeMap(String name, Class<?> type) {
		Class<?> superClass = type.getSuperclass();
		if(superClass != null && !superClass.equals(Object.class)){
			this.registerTypeMap(name,superClass);
			//递归找父类
			this.registerSuperClassTypeMap(name,superClass);
			//找父类实现的接口注册
			this.registerInterfaceTypeMap(name,superClass);
		}
	}

	private void registerTypeMap(String name, Class<?> type) {
		Set<String> names2type = this.typeMap.get(type);
		if(names2type == null){
			names2type = new HashSet<>();
			this.typeMap.put(type,names2type);
		}
		names2type.add(name);
	}

	@Override
	public Class<?> getType(String name) throws Exception{
		BeanDefinition bd = this.getBeanDefinition(name);
		Class<?> type = bd.getBeanClass();
		if (type != null) {
			if (StringUtils.isBlank(bd.getFactoryMethodName())) {
				// 构造方法来构造对象的,Type就是beanClass,不需做什么。
			} else {
				// 静态工厂方法方式的,反射获得Method,再获取Method的返回值类型
				type = type.getDeclaredMethod(bd.getFactoryMethodName(),null).getReturnType();
			}
		} else {
			// 工厂bean方式来构造对象的
			// 获得工厂Bean的Class
			type = this.getType(bd.getFactoryBeanName());
			// 再获得工厂方法的返回值类型
			type = type.getDeclaredMethod(bd.getFactoryMethodName(),null).getReturnType();
		}

		return type;
	}

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

	@Override
	public boolean containsBeanDefinition(String beanName) {

		return this.beanDefintionMap.containsKey(beanName);
	}

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

	@Override
	public <T> T getBean(Class<T> type) throws Exception {
		/*
		逻辑:
		1 获得其对应的所有的BeanDefinition
		2 如果只有一个,直接获取bean实例返回,否则
		3 遍历找出Primary的
		4 如果primary没有,或大于1个,抛出异常
		5 返回Primary的实例
		 */
		Set<String> names = this.typeMap.get(type);
		if(names != null) {
			if(names.size() == 1){
				return (T)this.getBean(names.iterator().next());
			}
			else {
				//找Primary
				BeanDefinition bd = null;
				String primaryName = null;
				StringBuilder nameStrings = new StringBuilder();
				for(String name : names){
					bd = this.getBeanDefinition(name);
					if(bd != null && bd.isPrimary()) {
						if(primaryName != null){
							String mess = type + " 类型的Bean存储多个Primary[" + primaryName + "," + name + "]";
							log.error(mess);
							throw new Exception(mess);
						}
						else {
							primaryName = name;
						}
					}
					nameStrings.append(" " + name);
				}

				if(primaryName != null){
					return (T)this.getBean(primaryName);
				}
				else {
					String mess = type + " 类型的Bean存在多个[" + nameStrings + "] 但无法确定Primary";
					log.error(mess);
					throw new Exception(mess);
				}
			}
		}
		return null;
	}

	@Override
	public <T> Map<String, T> getBeansOfType(Class<T> type) throws Exception {
		Set<String> names = this.typeMap.get(type);
		if(names != null) {
			Map<String, T> map = new HashMap<>();
			for(String name : names){
				map.put(name,(T) this.getBean(name));
			}
			return map;
		}
		return null;
	}

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

		/*单例如何实现?
			单例如何存储?
			如何保证单例?
		*/
		Object instance = singletonBeanMap.get(beanName);

		if (instance != null) {
			return instance;
		}

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

		if(bd.isSingleton()) { //如果是单例
			synchronized (this.singletonBeanMap) { //加锁
				instance = this.singletonBeanMap.get(beanName);
				if(instance == null){//第二次检查
					instance = doCreateInstance(bd);
					this.singletonBeanMap.put(beanName,instance);
				}
			}
		}
		else {
			instance = doCreateInstance(bd);
		}

		return instance;
	}

	private Object doCreateInstance(BeanDefinition bd) throws Exception {
		Class<?> type = bd.getBeanClass();
		Object instance = null;
		if (type != 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;
	}

	// 构造方法来构造对象
	private Object createInstanceByConstructor(BeanDefinition bd)
			throws InstantiationException, IllegalAccessException {
		try {
			return bd.getBeanClass().newInstance();
		} catch (SecurityException e1) {
			log.error("创建bean的实例异常,beanDefinition:" + bd, e1);
			throw e1;
		}
	}

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

	// 工厂bean方式来构造对象
	private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {

		Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
		Method m = factoryBean.getClass().getMethod(bd.getFactoryMethodName(), null);
		return m.invoke(factoryBean, null);
	}

	/**
	 * 执行初始化方法
	 * 
	 * @param bd
	 * @param instance
	 * @throws Exception
	 */
	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() throws IOException {
		// 执行单例实例的销毁方法
		for (Entry<String, BeanDefinition> e : this.beanDefintionMap.entrySet()) {
			String beanName = e.getKey();
			BeanDefinition bd = e.getValue();

			if (bd.isSingleton() && StringUtils.isNotBlank(bd.getDestroyMethodName())) {
				Object instance = this.singletonBeanMap.get(beanName);
				try {
					Method m = instance.getClass().getMethod(bd.getDestroyMethodName(), null);
					m.invoke(instance, null);
				} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
						| InvocationTargetException e1) {
					log.error("执行bean[" + beanName + "] " + bd + " 的 销毁方法异常!", e1);
				}
			}
		}

		//疑问:原型Bean如果指定了销毁方法,怎么办?
	}
}

Spring源码 -DI

  DI(Dependency injection)依赖注入。对象之间的依赖由容器在运行期决定,即容器动态的将某个依赖注入到对象之中。说的直白点就是给Bean对象的成员变量赋值。

BeanFactory获取实例

构造注入

需要通过构造方法来创建实例,然后对应的构造方法需要传入对应的参数。如果不是通过IoC来处理,可以直接通过如下的代码实现。

    public static void main(String[] args) {
        Boy boy = new Boy();
        Girl girl = new Girl("小丽",20,'C',boy);
    }

  通过直接赋值的方式就可以了。但是在IoC中需要通过反射的方式来处理。那么在通过反射操作的时候就需要能获取到对应的构造参数的依赖了,这时得分析怎么来存储的构造参数的依赖了。构造参数的依赖有两个特点:

  • 数量
  • 顺序

  上面的例子中的参数

  1. 小丽
  2. 20
  3. ‘C’
  4. boy,是一个依赖Bean

  参数可以有多个,完全可以通过List集合来存储,而且通过添加数据的顺序来决定构造参数的顺序了。但是这里有一个问题,如何表示Bean依赖呢?直接值直接添加到集合中就可以了,但是Bean依赖,还没有创建对应的对象,这时可以维护一个自定义对象,来绑定相关的关系。

BeanReference

  BeanReference就是用来说明bean依赖的:也就是这个属性依赖哪个类型的Bean
在这里插入图片描述

  可以根据name来依赖,也可以按照Type来依赖。当然程序中还有一点需要考虑,就是如何来区分是直接值还是Bean依赖呢?有了上面的设计其实就很容易判断了。

if ( obj instance BeanReference)

  当然还有一种比较复杂的情况如下:
在这里插入图片描述
  直接值是数组或者集合等,同时容器中的元素是Bean依赖,针对这种情况元素值还是需要用BeanReference来处理的。Bean工厂在处理时需要遍历替换。

3. BeanDefinition实现

  接下来看看如何具体的来实现DI基于构造参数依赖的相关操作。首先是定义的相关处理了。需要在 BeanDefinition中增加构造参数的获取的方法。
在这里插入图片描述

  然后需要在默认的实现GenericBeanDefinition中增加对应的方法来处理。

在这里插入图片描述

  定义后可以测试下对应的应用,定义个ABean,依赖了CBean

public class ABean {

	private String name;

	private CBean cb;

	public ABean(String name, CBean cb) {
		super();
		this.name = name;
		this.cb = cb;
		System.out.println("调用了含有CBean参数的构造方法");
	}

	public ABean(String name, CCBean cb) {
		super();
		this.name = name;
		this.cb = cb;
		System.out.println("调用了含有CCBean参数的构造方法");
	}

	public ABean(CBean cb) {
		super();
		this.cb = cb;
	}

	public void doSomthing() {
		System.out.println("Abean.doSomthing(): " + this.name + " cb.name=" + this.cb.getName());
	}

	public void init() {
		System.out.println("ABean.init() 执行了");
	}

	public void destroy() {
		System.out.println("ABean.destroy() 执行了");
	}
}

然后在实例化时需要做相关的绑定

		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setBeanClass(ABean.class);
		// 定义的构造参数的依赖
		List<Object> args = new ArrayList<>();
		args.add("abean01");
		// Bean依赖 通过BeanReference 来处理
		args.add(new BeanReference("cbean"));
		bd.setConstructorArgumentValues(args);
		bf.registerBeanDefinition("abean", bd);

构造参数传递后,接下来其实就需要要在 BeanFactory中来实现构造参数的注入了

4.BeanFactory实现

  前面在BeanFactory中实现Bean对象的创建有几种方式

  • 构造方法创建
  • 工厂静态方法
  • 工厂成员方法

  在通过构造方法创建其实是通过无参构造方法来处理的,这时需要改变这块的逻辑,通过有参构造方法来实现。

	// 构造方法来构造对象
	private Object createInstanceByConstructor(BeanDefinition bd)
			throws InstantiationException, IllegalAccessException {
		try {
			return bd.getBeanClass().newInstance();
		} catch (SecurityException e1) {
			log.error("创建bean的实例异常,beanDefinition:" + bd, e1);
			throw e1;
		}
	}

  就需要对上面的方法做出改变。

	// 构造方法来构造对象
	private Object createInstanceByConstructor(BeanDefinition bd)
			throws InstantiationException, IllegalAccessException {
        // 1. 得到真正的参数值
		List<?> constructorArgumentValues = bd.getConstructorArgumentValues(); 
        // 2.根据对应的构造参数依赖获取到对应的 Constructor 
        Constructor  constructor = 得到对应的构造方法
        // 3.用实际参数值调用构造方法创建对应的对象
        return constructor.newInstance(Object ... 实参值); 
	}

  通过上面的分析需要获取对应的构造器。这块需要通过反射来获取了。下面是具体的实现逻辑

在这里插入图片描述

  根据上面的分析,实现的逻辑分为两步

  1. 先根据参数的类型进行精确匹配查找,如果没有找到,继续执行第二步操作
  2. 获得所有的构造方法,遍历构造方法,通过参数数量过滤,再比对形参与实参的类型

  因为这里有个情况,实参是Boy,构造方法的形参是Person,第一种精确匹配就没有办法关联了。

在这里插入图片描述

具体的实现代码如下:

    private Constructor<?> determineConstructor(BeanDefinition bd, Object[] args) throws Exception {
        /*判定构造方法的逻辑应是怎样的?
        1 先根据参数的类型进行精确匹配查找,如未找到,则进行第2步查找;
        2获得所有的构造方法,遍历,通过参数数量过滤,再比对形参类型与实参类型。
        * */

        Constructor<?> ct = null;

        //没有参数,则用无参构造方法
        if (args == null) {
            return bd.getBeanClass().getConstructor(null);
        }

        // 1 先根据参数的类型进行精确匹配查找
        Class<?>[] paramTypes = new Class[args.length];
        int j = 0;
        for (Object p : args) {
            paramTypes[j++] = p.getClass();
        }
        try {
            ct = bd.getBeanClass().getConstructor(paramTypes);
        } catch (Exception e) {
            // 这个异常不需要处理
        }

        if (ct == null) {
            // 2 没有精确参数类型匹配的,获得所有的构造方法,遍历,通过参数数量过滤,再比对形参类型与实参类型。
            // 判断逻辑:先判断参数数量,再依次比对形参类型与实参类型
            outer:
            for (Constructor<?> ct0 : bd.getBeanClass().getConstructors()) {
                Class<?>[] paramterTypes = ct0.getParameterTypes();
                if (paramterTypes.length == args.length) {   //通过参数数量过滤
                    for (int i = 0; i < paramterTypes.length; i++) { //再依次比对形参类型与实参类型是否匹配
                        if (!paramterTypes[i].isAssignableFrom(args[i].getClass())) {
                            continue outer; //参数类型不可赋值(不匹配),跳到外层循环,继续下一个
                        }
                    }

                    ct = ct0;  //匹配上了
                    break outer;
                }
            }
        }

        if (ct != null) {
            return ct;
        } else {
            throw new Exception("不存在对应的构造方法!" + bd);
        }
    }

  上面考虑的是BeanFactory通过构造器来获取对象的逻辑,那如果是通过静态工厂方法或者成员工厂方法的方式来处理的,那么构造参数依赖的处理是否和前面的是一样的呢?其实是差不多的,需要根据对应的构造参数来推断对应的工厂方法

    // 静态工厂方法
    private Object createInstanceByStaticFactoryMethod(BeanDefinition bd) throws Exception {

        Object[] realArgs = this.getConstructorArgumentValues(bd);
        Class<?> type = bd.getBeanClass();
        Method m = this.determineFactoryMethod(bd, realArgs, type);
        return m.invoke(type, realArgs);
    }

    // 工厂bean方式来构造对象
    private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {

        Object[] realArgs = this.getConstructorArgumentValues(bd);
        Method m = this.determineFactoryMethod(bd, realArgs, this.getType(bd.getFactoryBeanName()));

        Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
        return m.invoke(factoryBean, realArgs);
    }

5.缓存功能

  对于上面的处理过程相信大家应该清楚了,通过推断也得到了对应的构造方法或者对应的工厂方法,那么可以不可以在下次需要再次获取的时候省略掉推导的过程呢?显然可以在BeanDefinition中增加缓存方法可以实现这个需求。

在这里插入图片描述

6. 循环依赖问题

在这里插入图片描述

  上图是循环依赖的三种情况,虽然方式有点不一样,但是循环依赖的本质是一样的,就你的完整创建要依赖与我,我的完整创建也依赖于你。相互依赖从而没法完整创建造成失败。

  通过构造参数依赖是完全可能出现上面的情况的,那么这种情况能解决吗?构造依赖的情况是解决不了的。

public class Test01 {

    public static void main(String[] args) {
        new TestService1();
    }
}

class TestService1{
    private TestService2 testService2 = new TestService2();
}

class TestService2{
    private  TestService1 testService1 = new TestService1();
}

  既然解决不了,那么在程序中如果出现了,应该要怎么来解决呢?其实可以在创建一个Bean的时候记录下这个Bean,当这个Bean创建完成后在移除这个Bean,然后在getBean的时候判断记录中是否有该Bean,如果有就判断为循环依赖,并抛出异常。数据结构可以通过Set集合来处理。

在这里插入图片描述
到此构造注入的实现就搞定了。

属性注入

 上面搞定了构造注入的方式。接下来再看看属性注入的方式有什么需要注意的地方。

1. 属性依赖分析

  属性依赖就是某个属性依赖某个值。

public class Girl {

    private String name;
    private int age;
    private char cup;
    private List<Boy> boyFriends;

    // ....
}

  那么在获取实例对象后如何根据相关的配置来给对应的属性来赋值呢?这时我们可以定义一个实体类 PropertyValue来记录相关的属性和值。
在这里插入图片描述

2.BeanDefinition实现

  这时我们就需要在BeanDefinition中关联相关属性信息了。
在这里插入图片描述

3.BeanFactory实现

  然后我们在BeanFactory的默认实现DefaultBeanFactory中实现属性值的依赖注入。

// 创建好实例对象
// 给属性依赖赋值
this.setPropertyDIValues(bd,instance);
// 执行初始化相关方法
this.doInit(bd,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()));

        }
    }

4.循环依赖问题

  在构造参数依赖中我们发现没有办法解决,在属性依赖中同样会存在循环依赖的问题,这时我们能解决吗?
在这里插入图片描述
  其实这种情况我们不在IoC场景下非常好解决。如下

Boy b = new Boy();
Girl g = new Girl();
b.setGirl(g);
g.setBoy(b);

  但是在IoC好像不是太好解决:
在这里插入图片描述
emsp; 针对这种情况我们需要通过 提前暴露来解决这个问题,具体看代码!!!

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

最后现阶段已经实现的类图结构
在这里插入图片描述

Spring源码手写篇-AOP

  手写IoC和DI后已经实现的类图结构。
在这里插入图片描述

一、AOP分析

在这里插入图片描述

1.AOP是什么?

   AOP[Aspect Oriented Programming] 面向切面编程,在不改变类的代码的情况下,对类方法进行功能的增强。

2.我们要做什么?

  需要在前面手写IoC,手写DI的基础上给用户提供AOP功能,让他们可以通过AOP技术实现对类方法功能增强。
在这里插入图片描述
在这里插入图片描述

二、AOP概念讲解

  上面在分析AOP需求的时候,我们介绍到了相关的概念,Advice、Pointcuts和weaving等,首先我们来看看在AOP中我们会接触到的相关的概念都有哪些。
在这里插入图片描述
更加形象的描述:
在这里插入图片描述
然后对于上面的相关概念,要考虑哪些是用户需要提供的,哪些是框架要写好的?
在这里插入图片描述
Advice,Pointcuts和Weaving各自的特点
在这里插入图片描述

三、切面实现

  通过上面的分析,我们要设计实现AOP功能,其实就是要设计实现上面分析的相关概念对应的组件。
在这里插入图片描述

1.Advice

1.1 面向接口编程

  Advice:通知,是由用户提供的,我们来使用,主要是用户提供就突出了 多变性。针对这块我们应该怎么设计?这里有两个问题:

  1. 我们如何能够识别用户提供的东西呢?用户在我们写好框架后使用我们的框架
  2. 如何让我们的代码隔绝用户提供的多变性呢?

针对这种情况我们定义一套标准的接口,用户通过实现接口类提供他们不同的逻辑

这里有个重要的设计原则大家要注意: 如何应对变化,通过面向接口编程来搞定!!!

我们先定义一个空的接口,可以先思考下我们为什么定义一个空的接口呢?
在这里插入图片描述

1.2 Advice的特点分析

  Advice的特点:可选时机,可选择在方法执行前、后、异常时进行功能的增强
在这里插入图片描述
结合上面的情况我们可以分析出Advice通知的几种情况

  • 前置增强-Before
  • 后置增强-AfterReturn
  • 环绕增强-Around
  • 最终通知-After
  • 异常通知-Throwing

有这么多的情况我们应该要怎么来实现呢?我们可以定义标准的接口方法,让用户来实现它,提供各种具体的增强内容。那么这四种增强相关的方法定义是怎样的呢?我们一一来分析下。

1.3 各种通知分析
1.3.1 前置增强

前置增强:在方法执行前进行增强。

问题1:它可能需要的参数?

  目的是对方法进行增强,应该需要的是方法相关的信息,我们使用它的时候能给如它的就是当前要执行方法的相关信息了

问题2:运行时方法有哪些信息?

  1. 方法本身 Method
  2. 方法所属的对象 Object
  3. 方法的参数 Object[]

问题3:前置增强的返回值是什么?

  在方法执行前进行增强,不需要返回值!

public interface MethodBeforeAdvice extends Advice {

	/**
	 * 实现该方法进行前置增强
	 * 
	 * @param method
	 *            被增强的方法
	 * @param args
	 *            方法的参数
	 * @param target
	 *            被增强的目标对象
	 * @throws Throwable
	 */
	void before(Method method, Object[] args, Object target) throws Throwable;
}
1.3.2 最终通知

  最终通知:在方法执行后进行增强

问题1:它可能需要的参数?

  • 方法本身 Method
  • 方法所属的对象 Object
  • 方法的参数 Object[]
  • 方法的返回值 Object 可能没有

问题2:它的返回值是什么?

  这个就需要看是否允许在After中更改返回的结果,如果规定只可用、不可修改返回值就不需要返回值

public interface AfterAdvice extends Advice {
	/**
	 * 实现该方法,提供后置增强
	 * 
	 * @param returnValue
	 *            返回值
	 * @param method
	 *            被增强的方法
	 * @param args
	 *            方法的参数
	 * @param target
	 *            方法的所属对象
	 * @throws Throwable
	 */
	void after(Object returnValue, Method method, Object[] args, Object target) throws Throwable;
}
1.3.3 后置通知

  后置增强:在方法执行后进行增强

问题1:他可能需要的参数

  • 方法本身 Method
  • 方法所属的对象 Object
  • 方法的参数 Object[]
  • 方法的返回值 Object

问题2:它的返回值是什么?

  这个就需要看是否允许在After中更改返回的结果,如果规定只可用、不可修改返回值就不需要返回值

public interface AfterReturningAdvice extends Advice {
	/**
	 * 实现该方法,提供AfterRetun增强
	 * 
	 * @param returnValue
	 *            返回值
	 * @param method
	 *            被增强的方法
	 * @param args
	 *            方法的参数
	 * @param target
	 *            方法的所属对象
	 * @throws Throwable
	 */
	void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;
}
1.3.4 环绕通知

Around环绕增强:包裹方法进行增强

问题1:他可能需要的参数

  • 方法本身 Method
  • 方法所属的对象 Object
  • 方法的参数 Object[]

问题2:它的返回值是面试?

  方法被它包裹,即方法将由它来执行,它需要返回方法的返回值

public interface MethodInterceptor extends Advice {
	/**
	 * 对方法进行环绕(前置、后置)增强、异常处理增强,方法实现中需调用目标方法。
	 * 
	 * @param method
	 *            被增强的方法
	 * @param args
	 *            方法的参数
	 * @param target
	 *            方法所属对象
	 * @return Object 返回值
	 * @throws Throwable
	 */
	Object invoke(Method method, Object[] args, Object target) throws Throwable;
}
1.3.5 异常通知

异常通知增强:对方法执行时的异常,进行增强处理

问题1:它可能需要什么参数?

  • 一定需要Exception
  • 可能需要方法本身 Method
  • 可能需要方法所属的对象 Object
  • 可能需要方法的参数 Object[]

问题2:它的返回值是什么?

  这个就需要看是否允许在After中更改返回的结果,如果规定只可用、不可修改返回值就不需要返回值

public interface ThrowsAdvice extends Advice {

    void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable;
}
1.4 Advice设计

  结合上面的分析,我们就可以得出Advice的体系图了
在这里插入图片描述

2.Pointcut

2.1 Pointcut的特点有:

  • 用户性:由用户指定
  • 变化性:用户可灵活指定
  • 多点性:用户可以选择在多个点上进行增强

2.2 Pointcut分析

  为用户提供一个东西,让他们可以灵活地指定多个方法点,而且我们还能看懂!

思考:切入点是由用户来指定在哪些方法点上进行增强,那么这个哪些方法点如何来表示能满足上面的需求呢?

分析:

  1. 指定哪些方法,是不是一个描述信息?
  2. 如何来指定一个方法?
  3. 如果有重载的情况怎么办?
  4. 123要求的其实就是一个完整的方法签名
com.yuyang.spring.aop.Girl.dbj(Boy,Time)

com.yuyang.spring.aop.Girl.dbj(Boy,Girl,Time)

我们还得进一步分析:如何做到多点性和灵活性,在一个描述中指定一类类的某些方法?

  • 某个包下的某个类的某个方法
  • 某个包下的所有类中的所有方法
  • 某个包下的所有类中的do开头的方法
  • 某个包下的以service结尾的类中的do开头的方法

也就是我们需要有这样一个表达式能够灵活的描述上面的这些信息。

这个表达式表达的内容有:
在这里插入图片描述
而且每个部分的要求是怎么样的呢?

  • 包名:有父子特点,要能模糊匹配
  • 类名:要能模糊匹配
  • 方法名:要能模糊匹配
  • 参数类型:参数可以有多个

那么设计的这个表达式将被我们用来决定是否需要对某个类的某个方法进行增强,这个决定过程应该是怎么样的?
在这里插入图片描述
针对需求的选择是:
在这里插入图片描述
AspectJ官网:http://www.eclipse.org/aspectj
在这里插入图片描述
切入点表达式要匹配的对象就是目标方法的方法名。所以,execution表达式中明显就是方法的签名。注意,表达式中加[ ]的部分表示可省略部分,各部分间用空格分开。在其中可以使用以下符号
在这里插入图片描述
举例:

execution(public * (. .))
指定切入点为:任意公共方法。
execution(
set (. .))
指定切入点为:任何一个以“set”开始的方法。
execution(
com.xyz.service..(. .))
指定切入点为:定义在service包里的任意类的任意方法。
execution(* com.xyz.service. ..(. .))
指定切入点为:定义在service包或者子包里的任意类的任意方法。“…”出现在类名中时,
后面必须跟“”,表示包、子包下的所有类。
execution(
.service..(. .))
指定只有一级包下的serivce子包下所有类(接口)中的所有方法为切入点
execution(
. .service..*(. .))
指定所有包下的serivce子包下所有类(接口)中的所有方法为切入点

2.3 Pointcut设计

  通过分析完成我们就该对Pointcut类设计了,接口,类。

思考1:首先考虑切入点应该具有的属性—>切入点表达式

思考2:切入点应对外提供什么行为

思考3:切入点被我们设计用来做什么?

  对类和方法进行匹配,切入点应该提供匹配类,匹配方法的行为

思考4:如果在我们设计的框架中要能灵活的扩展切点,我们应该如何设计?

  这又是一个要支持可多变的问题,像通知一样,我们定义一套标准接口,定义好基本行为,面向接口编程,屏蔽掉具体的实现。不管哪些方案,都实现匹配类,匹配方法的接口。
在这里插入图片描述
案例代码

public interface Pointcut {

	boolean matchsClass(Class<?> targetClass);

	boolean matchsMethod(Method method, Class<?> targetClass);
}

然后来看看AspectJ的实现

在这里插入图片描述
案例代码

public class AspectJExpressionPointcut implements Pointcut {

	private static PointcutParser pp = PointcutParser
			.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();

	private String expression;

	private PointcutExpression pe;

	public AspectJExpressionPointcut(String expression) {
		super();
		this.expression = expression;
		pe = pp.parsePointcutExpression(expression);
	}

	@Override
	public boolean matchsClass(Class<?> targetClass) {
		return pe.couldMatchJoinPointsInType(targetClass);
	}

	@Override
	public boolean matchsMethod(Method method, Class<?> targetClass) {
		ShadowMatch sm = pe.matchesMethodExecution(method);
		return sm.alwaysMatches();
	}

	public String getExpression() {
		return expression;
	}

}

3.切面Aspect

在这里插入图片描述
为此我们需要创建对应的接口来管理。

4. Advisor

为用户提供更简单的外观,Advisor(通知者)组合Advice和Pointcut。
在这里插入图片描述
当然扩展的形式比较多:
在这里插入图片描述

在这里插入图片描述

四、织入实现

1. 织入的分析

  织入要完成的是什么?织入其实就是要把用户提供的增强功能加到指定的方法上。
在这里插入图片描述
在什么时候织入?

  创建Bean实例的时候,在Bean初始化后,再对其进行增强。

如何确定bean要增强?

  对bean类及方法挨个匹配用户配置的切面,如果有切面匹配就是要增强

如何实现织入?

  代理方式

2.织入的设计

  为了更好的去设计织入的实现,先整理下AOP的使用流程。
在这里插入图片描述

这里要考虑匹配、织入逻辑写到哪里?是写在BeanFactory中吗?

这时要考虑如果我们直接在BeanFactory中来处理,后续如果还有其他的需求是不是也要在BeanFactory中处理呢?这样操作有什么不好的地方呢?

  • BeanFactory代码爆炸,不专情
  • 不易扩展

那应该要怎么来设计呢?

先来回顾下Bean的生产的过程

在这里插入图片描述
在这个过程中, 将来会有更多处理逻辑加入到Bean生产过程的不同阶段。我们现在最好是设计出能让我们后面不用再改BeanFactory的代码就能灵活的扩展。

这时我们可以考虑用观察者模式,通过在各个节点加入扩展点,加入注册机制。

在这里插入图片描述
那么在这块我们就应用观察者模式来加入一个Bean的后置处理器 BeanPostProcessor
在这里插入图片描述

3.织入的实现

3.1 分析

  我们先定义了 BeanPostProcessor 接口,在这个接口中我们定义了相关的行为,也就是初始化之前和初始化之后要执行的方法。
在这里插入图片描述
  那么在此处需要在BeanFactory对创建的Bean对象做初始化前后要校验是否需要做相关的增强操作。
在这里插入图片描述
 在BeanFactory中我们提供了BeanPostProcessor的注册方法。
在这里插入图片描述
在这里插入图片描述
那么结合BeanFactory要实现相关的Bean增强操作,我们要做的行为就是两方面

  1. 创建相关的BeanPostProcessor,并注册到BeanFactory中
  2. BeanFactory在初始化Bean前后判断是否有相关BeanPostProcessor,如果有做相关的增强处理

  有了上面的分析,那么我们要实现具体的织入就需要来看看在对应前置和后置方法中我们要实现的功能
在这里插入图片描述

3.2 判断是否需要增强

  我们如何判断Bean对象是否需要增强呢?其实就是需要判断该Bean是否满足用户定义的切入点表达式。也就是我们需要简单Bean所属的类和所有方法。然后遍历Advisor。取出advisor中的Pointcut来匹配类和方法。

在这里插入图片描述
代码层面

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws Throwable {

		/*逻辑
		1 判断Bean是否需要增强
		2 创建代理来实现增强
		*/

        //1 判断Bean是否需要增强
        List<Advisor> matchAdvisors = getMatchedAdvisors(bean, beanName);

		// 2如有切面切中,创建代理来实现增强
		if (CollectionUtils.isNotEmpty(matchAdvisors)) {
			bean = this.createProxy(bean, beanName, matchAdvisors);
		}

        return bean;
    }

在这里插入图片描述

3.3 代理对象

  通过上面的分析如果Bean需要被增强,那么我们就需要创建Bean对应的代理对象了。代理模式:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在调用者和目标对象之间起到中介的作用;

在这里插入图片描述
  动态代理的实现方法有哪些?
在这里插入图片描述
JDK动态代理:

在运行时,对接口创建代理对象

在这里插入图片描述
cglib动态代理:
在这里插入图片描述

3.4 代理实现层设计

  动态代理的实现方式有很多种,如何能够做到灵活的扩展呢?在这里我们同样可以通过 抽象面向接口编程来设计一套支持不同代理实现的代码
在这里插入图片描述
 有了上面的设计,然后就是需要考虑代理对象的创建了。
在这里插入图片描述

3.5 增强逻辑实现

  代理对象搞定后我们需要考虑核心的问题就是怎么来实现我们要增强的逻辑呢?首先不管你用哪种方式来生成代理对象最终增强的逻辑代码是一样的。所以我们可以把这部分内容提炼出来。
在这里插入图片描述
  然后具体的应用Advice增强实现的逻辑为:

在这里插入图片描述
注意此处用到了责任链模式

	public static Object applyAdvices(Object target, Method method, Object[] args, List<Advisor> matchAdvisors,
			Object proxy, BeanFactory beanFactory) throws Throwable {
		// 这里要做什么?   需要获取相关案例代码的+V:boge3306 备注:手写Spring
		// 1、获取要对当前方法进行增强的advice
		List<Object> advices = AopProxyUtils.getShouldApplyAdvices(target.getClass(), method, matchAdvisors,
				beanFactory);
		// 2、如有增强的advice,责任链式增强执行
		if (CollectionUtils.isEmpty(advices)) {
			return method.invoke(target, args);
		} else {
			// 责任链式执行增强
			AopAdviceChainInvocation chain = new AopAdviceChainInvocation(proxy, target, method, args, advices);
			return chain.invoke();
		}
	}

然后我们前面的Creator要怎么使用AopProxy呢?这块我们可以通过工厂模式来处理
在这里插入图片描述

public interface AopProxyFactory {

	AopProxy createAopProxy(Object bean, String beanName, List<Advisor> matchAdvisors, BeanFactory beanFactory)
			throws Throwable;

	/**
	 * 获得默认的AopProxyFactory实例
	 *    需要获取相关案例代码的+V:boge3306 备注:手写Spring
	 * @return AopProxyFactory
	 */
	static AopProxyFactory getDefaultAopProxyFactory() {
		return new DefaultAopProxyFactory();
	}
}

到这儿,完整的增强逻辑就梳理通了

Spring源码手写篇-Bean定义配置化

一、Bean定义配置分析

  我们前面实现了手写IoC和AOP的功能,但是我们在使用的时候发现我们的调用代码还是非常的繁琐,会给应用者很不好的体验。

在这里插入图片描述

  上面的代码很直观的看到重复代码很多,要用户设置的内容也很多,低效而且容易出错,这时我们可以看看在Spring中是怎么处理的呢?

一种是通过XML的配置文件方式

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="abean" class="com.study.spring.samples.ABean">
        <constructor-arg type="String" value="abean01" />
        <constructor-arg ref="cbean" />
    </bean>

    <bean id="cbean" class="com.study.spring.samples.CBean">
        <constructor-arg type="String" value="cbean01" />
    </bean>
</beans>

一种是通过注解的方式来处理

@Component
public class AController{

    @Autowired
    private Acc ac;
}

1. XML方式实现

基于XML方式实现我们需要做什么操作呢?

  • 定义XML规范
  • 要写代码来解析XML,完成Bean定义的注册

2.注解方式实现

基于XML方式实现我们需要做什么操作呢?

  • 定义一套注解
  • 要写代码来扫描、解析注解、完成Bean定义注册。

二、Bean定义配置实现

1. XML方法设计

  xml方式的流程如下:
在这里插入图片描述
写一个解析器,专门来解析对应的xml文件
在这里插入图片描述

2. 注解方式设计

2.1 定义相关的注解

  然后我们来看看需要定义的注解有哪些。

  • 类要不要配置为Bean @Component
  • BeanName Scope和Primary @Scope @Primary
  • 工厂方法 工厂Bean @Bean
  • 初始化方法、销毁方法 @PostConstruct @PreDestory
  • 构造参数依赖 @Autowired @Value
  • 属性依赖 @Qualifier
    在这里插入图片描述

2.2 扫描解析注册操作

   定义了相关注解后,谁来实现扫描注解、解析注解并完成Bean定义注册呢
在这里插入图片描述
如何实现扫描操作
在这里插入图片描述
实现的逻辑应该是递归找出包目录下的所有的.class 文件。

    public void scan(String... basePackages) throws Throwable {
        if (basePackages != null && basePackages.length > 0) {
            for (String p : basePackages) {
				/*
				 1 递归扫描包目录下的.class文件
				 2 组合包路径+class文件名 得到全限定类名
				 3 ClassLoad.load("类名") 得到 Class 对象
				 4 解析Class上的注解,获得Bean定义信息,注册Bean定义
				 */

                //1 递归扫描包目录下的.class文件
                Set<File> classFiles = this.doScan(p);
                //2 得到Class对象,并解析注解、注册Bean定义
                this.readAndRegisterBeanDefintion(classFiles);
            }
        }
    }

然后看看如何来解析类注解
在这里插入图片描述

  private void readAndRegisterBeanDefintion(Set<File> classFiles) throws BeanDefinitionRegistException {
        for (File classFile : classFiles) {
            String className = getClassNameFromFile(classFile);
            try {
                //加载类
                Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
                Component component = clazz.getAnnotation(Component.class);
                if (component != null) {// 标注了@Component注解
                    String beanName = component.value();
                    if (StringUtils.isBlank(beanName)) {
                        beanName = this.generateBeanName(clazz);
                    }
                    GenericBeanDefinition bd = new GenericBeanDefinition();
                    bd.setBeanClass(clazz);

                    //处理Scope
                    Scope scope = clazz.getAnnotation(Scope.class);
                    if (scope != null) {
                        bd.setScope(scope.value());
                    }
                    //处理primary
                    Primary primary = clazz.getAnnotation(Primary.class);
                    if (primary != null) {
                        bd.setPrimary(true);
                    }

                    // 处理构造方法,在构造方法上找@Autowired注解,如有,将这个构造方法set到bd;
                    this.handleConstructor(clazz, bd);

                    //处理方法上的注解(找出初始化、销毁、工厂方法)
                    this.handleMethod(clazz, bd, beanName);

                    // 处理属性依赖
                    this.handlePropertyDi(clazz, bd);

                    // 注册bean定义
                    this.registry.registerBeanDefinition(beanName, bd);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

3.ApplicationContext

  通过上面的设计,可以实现注解的方式来定义,但是整体体验还是不是很好,这时可以通过外观模式,为框架定义一个更简单的统一使用界面
在这里插入图片描述
组合为:
在这里插入图片描述

Spring源码篇-ApplicationContext

  前面通过手写IoC,DI、AOP和Bean的配置。到最后ApplicationContext的门面处理,对于Spring相关的核心概念应该会比较清楚了。接下来我们就看看在Spring源码中,对于的核心组件是如何实现的。

一、ApplicationContext

  ApplicationContext到底是什么?字面含义是应用的上下文。这块需要看看ApplicationContext的具体的结构。
在这里插入图片描述
emsp; 通过ApplicationContext实现的相关接口来分析,ApplicationContext接口在具备BeanFactory的功能的基础上还扩展了 应用事件发布,资源加载,环境参数国际化的能力。然后我们来看看ApplicationContext接口的实现类的情况。
在这里插入图片描述
  在ApplicationContext的实现类中有两个比较重要的分支 AbstractRefreshableApplicationContextGenericApplicationContext.
在这里插入图片描述

二、BeanFactory

  上面分析了 ApplicationContext接口的结构。然后来看看 BeanFactory在ApplicationContext中具体的实现是怎么样的
在这里插入图片描述
在这里插入图片描述
可以看到具体的实现是 DefaultListableBeanFactory .然后来看看他的体系结构
在这里插入图片描述
BeanFactory的继承体系
在这里插入图片描述

三、BeanDefinition

  然后来了解下ApplicationContext是如何来加载Bean定义的。具体代码需要分为XML配置文件和基于注解的两种方式来看。

1.基于XML方式

  我们先定义对应的application.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

	<bean id="beanE" class="com.study.spring.sample.config.BeanE" />

	<bean id="beanF" class="com.study.spring.sample.config.BeanF" ></bean>

	<context:annotation-config/>

	<context:component-scan base-package="com.study.spring.sample.config" ></context:component-scan>

</beans>

然后我们的测试类代码

public class XMLConfigMain {

	public static void main(String[] args) {
		ApplicationContext context = new GenericXmlApplicationContext(
				"classpath:com/study/spring/sample/config/application.xml");
		BeanF bf = context.getBean(BeanF.class);
		bf.do1();
	}
}

处理的过程 解析XML --> BeanDefinition --> BeanDefinitionRegistry --> BeanFactory
在这里插入图片描述

Spring初始化源码分析

  接下来我们详细分析下refresh方法的作用。

一、refresh方法

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
		    // 1.context 为刷新做准备
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 2.让子类实现刷新内部持有BeanFactory
			//完成beanFactory的创建//
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 3.对beanFactory做一些准备工作:注册一些context回调、bean等
			//beanFactory的准备工作//
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 4.调用留给子类来提供实现逻辑的 对BeanFactory进行处理的钩子方法
				// 子类扩展实现的方法 //
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 5.执行context中注册的 BeanFactoryPostProcessor bean
				//调用beanFactory的后置处理器 //
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 6.注册BeanPostProcessor: 获得用户注册的BeanPostProcessor实例,注册到BeanFactory上
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 7.初始化国际化资源
				initMessageSource();

				// Initialize event multicaster for this context.
				// 8.初始化Application event 广播器
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 9.执行 有子类来提供实现逻辑的钩子方法 onRefresh
				onRefresh();

				// Check for listener beans and register them.
				// 10.注册ApplicationListener: 获得用户注册的ApplicationListener Bean实例,注册到广播器上
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 11、完成剩余的单例Bean的实例化
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 12 发布对应的事件
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

二、prepareRefresh

  完成一些刷新前的准备工作.

	protected void prepareRefresh() {
		// Switch to active.
		this.startupDate = System.currentTimeMillis();
// 设置相关的状态
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

三、obtainFreshBeanFactory

  在obtainFreshBeanFactory方法会完成BeanFactory对象的创建。

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 刷新容器
		refreshBeanFactory();
		return getBeanFactory();
	}

如果是基于XML的方式使用会在refreshBeanFactory中完成配置文件的加载解析操作

	@Override
	protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
            // 销毁前面的 BeanFactory
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 创建 BeanFactory 对象
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory); // 加载解析配置文件
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

四、prepareBeanFactory

  上面的obtainFreshBeanFactory中完成了BeanFactory的创建和相关BeanDefinition对象的组装,然后在接下来的prepareBeanFactory中会完成相关的准备工作。

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		// 设置beanFactory的classloader为当前context的classloader
		beanFactory.setBeanClassLoader(getClassLoader());
		// 设置beanfactory的表达式语言处理器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		// 为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具类
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 添加beanPostProcessor,ApplicationContextAwareProcessor此类用来完成某些Aware对象的注入
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 设置要忽略自动装配的接口,很多同学理解不了为什么此处要对这些接口进行忽略,原因非常简单,这些接口的实现是由容器通过set方法进行注入的,
		// 所以在使用autowire进行注入的时候需要将这些接口进行忽略
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		// 设置几个自动装配的特殊规则,当在进行ioc初始化的如果有多个实现,那么就使用指定的对象进行注入
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 注册BPP
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 增加对AspectJ的支持,在java中织入分为三种方式,分为编译器织入,类加载器织入,运行期织入,编译器织入是指在java编译器,采用特殊的编译器,将切面织入到java类中,
		// 而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面,运行期织入则是采用cglib和jdk进行切面的织入
		// aspectj提供了两种织入方式,第一种是通过特殊编译器,在编译器,将aspectj语言编写的切面类织入到java类中,第二种是类加载期织入,就是下面的load time weaving,此处后续讲
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		// 注册默认的系统环境bean到一级缓存中
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

五、postProcessBeanFactory

  该方法是一个空方法,交给子类自己处理的方法

六、invokeBeanFactoryPostProcessors

  invokeBeanFactoryPostProcessors是BeanFactory的后置处理方法。核心是会完成注册的BeanFactoryPostProcessor接口和BeanDefinitionRegistryPostProcessor的相关逻辑。invokeBeanFactoryPostProcessors是其核心的方法。

    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        // 无论是什么情况,优先执行BeanDefinitionRegistryPostProcessors
        // 将已经执行过的BFPP存储在processedBeans中,防止重复执行
        Set<String> processedBeans = new HashSet<>();

        // 判断beanfactory是否是BeanDefinitionRegistry类型,此处是DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口,所以为true
        if (beanFactory instanceof BeanDefinitionRegistry) {
            // 类型转换
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 此处希望大家做一个区分,两个接口是不同的,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子集
            // BeanFactoryPostProcessor主要针对的操作对象是BeanFactory,而BeanDefinitionRegistryPostProcessor主要针对的操作对象是BeanDefinition
            // 存放BeanFactoryPostProcessor的集合
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 存放BeanDefinitionRegistryPostProcessor的集合
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 首先处理入参中的beanFactoryPostProcessors,遍历所有的beanFactoryPostProcessors,将BeanDefinitionRegistryPostProcessor
            // 和BeanFactoryPostProcessor区分开
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果是BeanDefinitionRegistryPostProcessor
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 直接执行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    // 添加到registryProcessors,用于后续执行postProcessBeanFactory方法
                    registryProcessors.add(registryProcessor);
                } else {
                    // 否则,只是普通的BeanFactoryPostProcessor,添加到regularPostProcessors,用于后续执行postProcessBeanFactory方法
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
            // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 遍历处理所有符合规则的postProcessorNames
            for (String ppName : postProcessorNames) {
                // 检测是否实现了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 按照优先级进行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 调用所有实现Ordered接口的BeanDefinitionRegistryPostProcessor实现类
            // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,
            // 此处需要重复查找的原因在于上面的执行过程中可能会新增其他的BeanDefinitionRegistryPostProcessor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 检测是否实现了Ordered接口,并且还未执行过
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 按照优先级进行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后,调用所有剩下的BeanDefinitionRegistryPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                // 遍历执行
                for (String ppName : postProcessorNames) {
                    // 跳过已经执行过的BeanDefinitionRegistryPostProcessor
                    if (!processedBeans.contains(ppName)) {
                        // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }
                // 按照优先级进行排序操作
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
                registryProcessors.addAll(currentRegistryProcessors);
                // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 执行完毕之后,清空currentRegistryProcessors
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            // 最后,调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // Invoke factory processors registered with the context instance.
            // 如果beanFactory不归属于BeanDefinitionRegistry类型,那么直接执行postProcessBeanFactory方法
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 到这里为止,入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,下面开始处理容器中
        // 所有的BeanFactoryPostProcessor
        // 可能会包含一些实现类,只实现了BeanFactoryPostProcessor,并没有实现BeanDefinitionRegistryPostProcessor接口

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // 找到所有实现BeanFactoryPostProcessor接口的类
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
//		List<String> orderedPostProcessorNames = new ArrayList<>();
        List<BeanFactoryPostProcessor> orderedPostProcessor = new ArrayList<>();
        // 用于存放普通BeanFactoryPostProcessor的beanName
//		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        List<BeanFactoryPostProcessor> nonOrderedPostProcessorNames = new ArrayList<>();
        // 遍历postProcessorNames,将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
        for (String ppName : postProcessorNames) {
            // 跳过已经执行过的BeanFactoryPostProcessor
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            // 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessors
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            // 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName到orderedPostProcessorNames
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//				orderedPostProcessorNames.add(ppName);
                orderedPostProcessor.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            } else {
                // 添加剩下的普通BeanFactoryPostProcessor的beanName到nonOrderedPostProcessorNames
//				nonOrderedPostProcessorNames.add(ppName);
                nonOrderedPostProcessorNames.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        // 对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 遍历实现了PriorityOrdered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 创建存放实现了Ordered接口的BeanFactoryPostProcessor集合
//		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        // 遍历存放实现了Ordered接口的BeanFactoryPostProcessor名字的集合
//		for (String postProcessorName : orderedPostProcessorNames) {
        // 将实现了Ordered接口的BeanFactoryPostProcessor添加到集合中
//			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//		}
        // 对实现了Ordered接口的BeanFactoryPostProcessor进行排序操作
//		sortPostProcessors(orderedPostProcessors, beanFactory);
        sortPostProcessors(orderedPostProcessor, beanFactory);
        // 遍历实现了Ordered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
//		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessor, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // 最后,创建存放普通的BeanFactoryPostProcessor的集合
//		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        // 遍历存放实现了普通BeanFactoryPostProcessor名字的集合
//		for (String postProcessorName : nonOrderedPostProcessorNames) {
        // 将普通的BeanFactoryPostProcessor添加到集合中
//			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//		}
        // 遍历普通的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
//		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessorNames, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        // 清除元数据缓存(mergeBeanDefinitions、allBeanNamesByType、singletonBeanNameByType)
        // 因为后置处理器可能已经修改了原始元数据,例如,替换值中的占位符
        beanFactory.clearMetadataCache();
    }

要搞清楚上面的代码含义首先需要搞清楚出这两者之间的关系
在这里插入图片描述
实现的核心流程是
在这里插入图片描述
在这个位置核心的代表是 ConfigurationClassPostProcessor用来处理 @Configuration注解表示的Java类,来处理其中的@Bean,@Primary等注解。

七、registerBeanPostProcessors

  完成Bean对象的相关后置处理器的注册。具体的代码逻辑和上面是差不多的。

   /**
     * 注册beanPostProcessor
     * @param beanFactory
     * @param applicationContext
     */
    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

        // 找到所有实现了BeanPostProcessor接口的类
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // Register BeanPostProcessorChecker that logs an info message when
        // a bean is created during BeanPostProcessor instantiation, i.e. when
        // a bean is not eligible for getting processed by all BeanPostProcessors.
        // 记录下BeanPostProcessor的目标计数
        // 此处为什么要+1呢,原因非常简单,在此方法的最后会添加一个BeanPostProcessorChecker的类
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        // 添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 定义存放实现了PriorityOrdered接口的BeanPostProcessor集合
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 定义存放spring内部的BeanPostProcessor
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        // 定义存放实现了Ordered接口的BeanPostProcessor的name集合
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 定义存放普通的BeanPostProcessor的name集合
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        // 遍历beanFactory中存在的BeanPostProcessor的集合postProcessorNames,
        for (String ppName : postProcessorNames) {
            // 如果ppName对应的BeanPostProcessor实例实现了PriorityOrdered接口,则获取到ppName对应的BeanPostProcessor的实例添加到priorityOrderedPostProcessors中
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            // 如果ppName对应的BeanPostProcessor实例没有实现PriorityOrdered接口,但是实现了Ordered接口,那么将ppName对应的bean实例添加到orderedPostProcessorNames中
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                // 否则将ppName添加到nonOrderedPostProcessorNames中
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, register the BeanPostProcessors that implement PriorityOrdered.
        // 首先,对实现了PriorityOrdered接口的BeanPostProcessor实例进行排序操作
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 注册实现了PriorityOrdered接口的BeanPostProcessor实例添加到beanFactory中
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // Next, register the BeanPostProcessors that implement Ordered.
        // 注册所有实现Ordered的beanPostProcessor
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String ppName : orderedPostProcessorNames) {
            // 根据ppName找到对应的BeanPostProcessor实例对象
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            // 将实现了Ordered接口的BeanPostProcessor添加到orderedPostProcessors集合中
            orderedPostProcessors.add(pp);
            // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        // 对实现了Ordered接口的BeanPostProcessor进行排序操作
        sortPostProcessors(orderedPostProcessors, beanFactory);
        //  注册实现了Ordered接口的BeanPostProcessor实例添加到beanFactory中
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // Now, register all regular BeanPostProcessors.
        // 创建存放没有实现PriorityOrdered和Ordered接口的BeanPostProcessor的集合
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        // 遍历集合
        for (String ppName : nonOrderedPostProcessorNames) {
            // 根据ppName找到对应的BeanPostProcessor实例对象
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            // 将没有实现PriorityOrdered和Ordered接口的BeanPostProcessor添加到nonOrderedPostProcessors集合中
            nonOrderedPostProcessors.add(pp);
            // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        //  注册没有实现PriorityOrdered和Ordered的BeanPostProcessor实例添加到beanFactory中
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // Finally, re-register all internal BeanPostProcessors.
        // 将所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor进行排序操作
        sortPostProcessors(internalPostProcessors, beanFactory);
        // 注册所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor到beanFactory中
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        // 注册ApplicationListenerDetector到beanFactory中
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

八、initMessageSource

  为上下文初始化message源,即不同语言的消息体,国际化处理.此处不过多介绍、

九、initApplicationEventMulticaster

  initApplicationEventMulticaster初始化事件监听多路广播器.

protected void initApplicationEventMulticaster() {
		// 获取当前bean工厂,一般是DefaultListableBeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		// 判断容器中是否存在bdName为applicationEventMulticaster的bd,也就是说自定义的事件监听多路广播器,必须实现ApplicationEventMulticaster接口
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			// 如果有,则从bean工厂得到这个bean对象
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			// 如果没有,则默认采用SimpleApplicationEventMulticaster
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}

代码很简单,创建了一个SimpleApplicationEventMulticaster对象,来广播相关的消息事件。

十、onRefresh

  留给子类来初始化其他的bean

十一、registerListeners

  所有注册的bean中查找listener bean,注册到消息广播器中.

	protected void registerListeners() {
		// Register statically specified listeners first.
		// 遍历应用程序中存在的监听器集合,并将对应的监听器添加到监听器的多路广播器中
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		// 从容器中获取所有实现了ApplicationListener接口的bd的bdName
		// 放入ApplicationListenerBeans集合中
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
//			getApplicationEventMulticaster().addApplicationListener(this.getBean(listenerBeanName,ApplicationListener.class));
		}

		// Publish early application events now that we finally have a multicaster...
		// 此处先发布早期的监听器集合
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

十二、finishBeanFactoryInitialization

  finishBeanFactoryInitialization初始化剩下的单实例(非懒加载的).具体请看 Bean的实例化

十三、finishRefresh

  finishRefresh完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人.

protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		// 清除上下文级别的资源缓存(如扫描的ASM元数据)
		// 清空在资源加载器中的所有资源缓存
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		// 为这个上下文初始化生命周期处理器
		// 初始化LifecycleProcessor.如果上下文中找到'lifecycleProcessor'的LifecycleProcessor Bean对象,
		// 则使用DefaultLifecycleProcessor
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		// 首先将刷新传播到生命周期处理器
		// 上下文刷新的通知,例如自动启动的组件
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		// 发布最终事件
		// 新建ContextRefreshedEvent事件对象,将其发布到所有监听器。
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		// 参与LiveBeansView MBean,如果是活动的
		// LiveBeansView:Sping用于支持JMX 服务的类
		// 注册当前上下文到LiveBeansView,以支持JMX服务
		LiveBeansView.registerApplicationContext(this);
	}

Spring源码-Bean的实例化

一、BeanDefinition

  首先我们来看看BeanDefinition的存放位置。因为Bean对象的实例化肯定是BeanFactory基于对应的BeanDefinition的定义来实现的,所以在这个过程中BeanDefinition是非常重要的,前面的课程讲解已经完成了BeanDefinition的定义。同时根据前面refresh方法的讲解我们知道了BeanFactory的具体实现是 DefaultListableBeanFactory.所以BeanDefinition的相关信息是存储在 DefaultListableBeanFactory的相关属性中的。

/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new
ConcurrentHashMap<>(256);

二、Bean实例的创建过程

  然后就是Bean实例的创建过程。这块儿我们可以通过Debug的形式非常直观的看到。
在这里插入图片描述

三、单例对象

  在创建单例对象的时候是如何保存单例的特性的?这块我们需要注意下面的代码
在这里插入图片描述
然后进入到getSingleton方法中。
在这里插入图片描述
创建成功的单例对象会被缓存起来。在 addSingleton 方法中
在这里插入图片描述
在这里插入图片描述
所以singletonObjects是缓存所有Bean实例的容器
在这里插入图片描述
而具体创建单例Bean的逻辑会回调前面的Lambda表达式中的createBean方法
在这里插入图片描述
在这里插入图片描述

四、单例对象的销毁

  然后 来看下一个单例Bean对象的销毁过程。定义一个案例
在这里插入图片描述
然后我们在测试的案例中显示的调用 close方法
在这里插入图片描述
执行的时候可以看到相关的日志执行了。

在这里插入图片描述
进入到close方法中分析,比较核心的有两个位置。在doClose方法中。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
具体销毁的代码进入destroyBeans()中查看即可。

在doClose方法中有个提示。registerShutdownHook方法
在这里插入图片描述

@Override
	public void registerShutdownHook() {
		if (this.shutdownHook == null) {
			// No shutdown hook registered yet.
			this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
				@Override
				public void run() {
					synchronized (startupShutdownMonitor) {
						doClose();
					}
				}
			};
			Runtime.getRuntime().addShutdownHook(this.shutdownHook);
		}
	}

对应的在web项目中就有对应的调用
在这里插入图片描述
这个就是Bean实例化的过程了

Spring源码-DI的过程

  接下来我们分析下Spring源码中Bean初始化过程中的DI过程。也就是属性的依赖注入。

一、构造参数依赖

1. 如何确定构造方法

  在Spring中生成Bean实例的时候默认是调用对应的无参构造方法来处理。

@Component
public class BeanK {

    private BeanE beanE;
    private BeanF beanF;

  
    public BeanK(BeanE beanE) {
        this.beanE = beanE;
    }

    public BeanK(BeanE beanE, BeanF beanF) {
        this.beanE = beanE;
        this.beanF = beanF;
    }
}

声明了两个构造方法,但是没有提供无参的构造方法。这时从容器中获取会报错。
在这里插入图片描述
这时我们需要在显示使用的构造方法中添加@Autowired注解即可

在这里插入图片描述
源码层面的核心

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		// 确认需要创建的bean实例的类可以实例化
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		// 确保class不为空,并且访问权限是public
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		// 判断当前beanDefinition中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		// 如果工厂方法不为空则使用工厂方法初始化策略
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
		// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析

		// Shortcut when re-creating the same bean...
		// 标记下,防止重复创建同一个bean
		boolean resolved = false;
		// 是否需要自动装配
		boolean autowireNecessary = false;
		// 如果没有参数
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				// 因为一个类可能由多个构造函数,所以需要根据配置文件中配置的参数或传入的参数来确定最终调用的构造函数。
				// 因为判断过程会比较,所以spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
				// 在下次创建相同时直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		// 有构造参数的或者工厂方法
		if (resolved) {
			// 构造器有参数
			if (autowireNecessary) {
				// 构造函数自动注入
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				// 使用默认构造函数构造
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		// 从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有@Autowired注解构造
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		// 以下情况符合其一即可进入
		// 1、存在可选构造方法
		// 2、自动装配模型为构造函数自动装配
		// 3、给BeanDefinition中设置了构造参数值
		// 4、有参与构造函数参数列表的参数
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		// 找出最合适的默认构造方法
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			// 构造函数自动注入
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		// 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
		return instantiateBean(beanName, mbd);
	}

2. 循环依赖

  接下来我们看看在构造注入的情况下。对循环依赖的检测是怎么做的。前面我们分析过,在构造注入的情况下,对于循环依赖是没有办法解决的。只能检测,然后抛出对应的异常信息。

@Component
public class BeanL {

    private BeanM beanM;

    @Autowired
    public BeanL(BeanM beanM) {
        this.beanM = beanM;
    }
}

@Component
public class BeanM {
    private BeanL beanL;

    @Autowired
    public BeanM(BeanL beanL) {
        this.beanL = beanL;
    }
}

然后启动代码看到循环依赖的报错
在这里插入图片描述
然后我们来看看他是如何实现循环检测的。
在这里插入图片描述
进入到这个 beforeSingletonCreation方法中。

protected void beforeSingletonCreation(String beanName) {
		// 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName添加到当前正在创建的bean名称列表后,出现
		// beanName已经在当前正在创建的bean名称列表中添加过
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			// 抛出当前正在创建的Bean异常
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

然后当对象创建完成后。会异常对应的检测
在这里插入图片描述

protected void afterSingletonCreation(String beanName) {
		// 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName从当前正在创建的bean名称列表异常后,出现
		// beanName已经没在当前正在创建的bean名称列表中出现过
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			// 抛出非法状态异常:单例'beanName'不是当前正在创建的
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}

当然上面的针对单例的处理,如果是原型的话。我们继续来看

// 原型模式的bean对象创建
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					// 它是一个原型 -> 创建一个新实例
					// 定义prototype实例
					Object prototypeInstance = null;
					try {
						// 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中
						beforePrototypeCreation(beanName);
						// 为mbd(和参数)创建一个bean实例
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除
						afterPrototypeCreation(beanName);
					}
					// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是
					// FactoryBean会直接返回beanInstance实例
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

在这里插入图片描述
而且我们可以发现在原型对象的检测中使用的是ThreadLocal来存储了
在这里插入图片描述

二、属性依赖

  然后我们来看看Bean的属性依赖的处理。属性依赖的具体方法是 polulateBean

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		// 如果beanWrapper为空
		if (bw == null) {
			// 如果mbd有需要设置的属性
			if (mbd.hasPropertyValues()) {
				// 抛出bean创建异常
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				// 没有可填充的属性,直接跳过
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		// 给任何实现了InstantiationAwareBeanPostProcessors的子类机会去修改bean的状态再设置属性之前,可以被用来支持类型的字段注入

		// 否是"synthetic"。一般是指只有AOP相关的pointCut配置或者Advice配置才会将 synthetic设置为true
		// 如果mdb是不是'syntheic'且工厂拥有InstantiationAwareBeanPostProcessor
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			//遍历工厂中的BeanPostProcessor对象
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				//如果 bp 是 InstantiationAwareBeanPostProcessor 实例
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					// //postProcessAfterInstantiation:一般用于设置属性
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
		//PropertyValues:包含以一个或多个PropertyValue对象的容器,通常包括针对特定目标Bean的一次更新
		//如果mdb有PropertyValues就获取其PropertyValues
 		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		// 获取 mbd 的 自动装配模式
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		// 如果 自动装配模式 为 按名称自动装配bean属性 或者 按类型自动装配bean属性
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			//MutablePropertyValues:PropertyValues接口的默认实现。允许对属性进行简单操作,并提供构造函数来支持从映射 进行深度复制和构造
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			// 根据autotowire的名称(如适用)添加属性值
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				//通过bw的PropertyDescriptor属性名,查找出对应的Bean对象,将其添加到newPvs中
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			// 根据自动装配的类型(如果适用)添加属性值
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				//通过bw的PropertyDescriptor属性类型,查找出对应的Bean对象,将其添加到newPvs中
				autowireByType(beanName, mbd, bw, newPvs);
			}
			//让pvs重新引用newPvs,newPvs此时已经包含了pvs的属性值以及通过AUTOWIRE_BY_NAME,AUTOWIRE_BY_TYPE自动装配所得到的属性值
			pvs = newPvs;
		}

		//工厂是否拥有InstiationAwareBeanPostProcessor
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//mbd.getDependencyCheck(),默认返回 DEPENDENCY_CHECK_NONE,表示 不检查
		//是否需要依赖检查
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		//经过筛选的PropertyDesciptor数组,存放着排除忽略的依赖项或忽略项上的定义的属性
		PropertyDescriptor[] filteredPds = null;
		//如果工厂拥有InstiationAwareBeanPostProcessor,那么处理对应的流程,主要是对几个注解的赋值工作包含的两个关键子类是CommonAnnoationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor
		if (hasInstAwareBpps) {
			//如果pvs为null
			if (pvs == null) {
				//尝试获取mbd的PropertyValues
				pvs = mbd.getPropertyValues();
			}
			//遍历工厂内的所有后置处理器
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				//如果 bp 是 InstantiationAwareBeanPostProcessor 的实例
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					//将bp 强转成 InstantiationAwareBeanPostProcessor 对象
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//postProcessProperties:在工厂将给定的属性值应用到给定Bean之前,对它们进行后处理,不需要任何属性扫描符。该回调方法在未来的版本会被删掉。
					// -- 取而代之的是 postProcessPropertyValues 回调方法。
					// 让ibp对pvs增加对bw的Bean对象的propertyValue,或编辑pvs的proertyValue
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					//如果pvs为null
					if (pvsToUse == null) {
						//如果filteredPds为null
						if (filteredPds == null) {
							//mbd.allowCaching:是否允许缓存,默认时允许的。缓存除了可以提高效率以外,还可以保证在并发的情况下,返回的PropertyDesciptor[]永远都是同一份
							//从bw提取一组经过筛选的PropertyDesciptor,排除忽略的依赖项或忽略项上的定义的属性
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						//postProcessPropertyValues:一般进行检查是否所有依赖项都满足,例如基于"Require"注释在 bean属性 setter,
						// 	-- 替换要应用的属性值,通常是通过基于原始的PropertyValues创建一个新的MutablePropertyValue实例, 添加或删除特定的值
						// 	-- 返回的PropertyValues 将应用于bw包装的bean实例 的实际属性值(添加PropertyValues实例到pvs 或者 设置为null以跳过属性填充)
						//回到ipd的postProcessPropertyValues方法
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						//如果pvsToUse为null,将终止该方法精致,以跳过属性填充
						if (pvsToUse == null) {
							return;
						}
					}
					//让pvs引用pvsToUse
					pvs = pvsToUse;
				}
			}
		}
		//如果需要依赖检查
		if (needsDepCheck) {
			//如果filteredPds为null
			if (filteredPds == null) {
				//从bw提取一组经过筛选的PropertyDesciptor,排除忽略的依赖项或忽略项上的定义的属性
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			//检查依赖项:主要检查pd的setter方法需要赋值时,pvs中有没有满足其pd的需求的属性值可供其赋值
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		//如果pvs不为null
		if (pvs != null) {
			//应用给定的属性值,解决任何在这个bean工厂运行时其他bean的引用。必须使用深拷贝,所以我们 不会永久地修改这个属性
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

1. 提前暴露

  然后来看看是如何处理循环依赖的。
在这里插入图片描述
对应的 addSingletonFactory方法

	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		// 使用singletonObjects进行加锁,保证线程安全
		synchronized (this.singletonObjects) {
			// 如果单例对象的高速缓存【beam名称-bean实例】没有beanName的对象
			if (!this.singletonObjects.containsKey(beanName)) {
				// 将beanName,singletonFactory放到单例工厂的缓存【bean名称 - ObjectFactory】
				this.singletonFactories.put(beanName, singletonFactory);
				// 从早期单例对象的高速缓存【bean名称-bean实例】 移除beanName的相关缓存对象
				this.earlySingletonObjects.remove(beanName);
				// 将beanName添加已注册的单例集中
				this.registeredSingletons.add(beanName);
			}
		}
	}

2. 循环依赖

循环依赖的图解
在这里插入图片描述
在这里插入图片描述
相关代码介绍
在这里插入图片描述
getEarlyBeanReference方法

在这里插入图片描述

getSingleton方法
在这里插入图片描述

Spring源码-AOP分析

1. 涉及的相关概念

  先回顾下核心的概念,比如:Advice,Pointcut,Aspect等
在这里插入图片描述
更加形象的描述:
在这里插入图片描述

2. 相关核心的设计

Advice:
在这里插入图片描述
Pointcut:
在这里插入图片描述
Aspect:
在这里插入图片描述
织入:
在这里插入图片描述
在这里插入图片描述

二、AOP相关概念的类结构

1. Advice类结构

  我们先来看看Advice的类结构,advice–》通知,需要增强的功能
在这里插入图片描述
相关的说明
在这里插入图片描述

2. Pointcut类结构

  然后来看看Pointcut的设计,也就是切入点的处理。
在这里插入图片描述
Pointcut的两种实现方式
在这里插入图片描述

3. Advisor类结构

  Advisor的类结构比较简单。一个是PointcutAdvisor,一个是IntroductionAdvisor
在这里插入图片描述
要看的重点是 PointcutAdvisor 及实现 AspectJPointcutAdvisor。

三、织入的实现

1. BeanPostProcessor

1.1 案例演示

  通过案例来看,首先使用AOP来增强。

定义切面类

/**
 * 切面类
 */
@Component
@EnableAspectJAutoProxy
@Aspect
public class AspectAdviceBeanUseAnnotation {

	// 定义一个全局的Pointcut
	@Pointcut("execution(* com.study.spring.sample.aop.*.do*(..))")
	public void doMethods() {
	}

	@Pointcut("execution(* com.study.spring.sample.aop.*.service*(..))")
	public void services() {
	}

	// 定义一个Before Advice
	@Before("doMethods() and args(tk,..)")
	public void before3(String tk) {
		System.out.println("----------- AspectAdviceBeanUseAnnotation before3  增强  参数tk= " + tk);
	}

	@Around("services() and args(name,..)")
	public Object around2(ProceedingJoinPoint pjp, String name) throws Throwable {
		System.out.println("--------- AspectAdviceBeanUseAnnotation arround2 参数 name=" + name);
		System.out.println("----------- AspectAdviceBeanUseAnnotation arround2 环绕-前增强 for " + pjp);
		Object ret = pjp.proceed();
		System.out.println("----------- AspectAdviceBeanUseAnnotation arround2 环绕-后增强 for " + pjp);
		return ret;
	}

	@AfterReturning(pointcut = "services()", returning = "retValue")
	public void afterReturning(Object retValue) {
		System.out.println("----------- AspectAdviceBeanUseAnnotation afterReturning 增强 , 返回值为: " + retValue);
	}

	@AfterThrowing(pointcut = "services()", throwing = "e")
	public void afterThrowing(JoinPoint jp, Exception e) {
		System.out.println("----------- AspectAdviceBeanUseAnnotation afterThrowing 增强  for " + jp);
		System.out.println("----------- AspectAdviceBeanUseAnnotation afterThrowing 增强  异常 :" + e);
	}

	@After("doMethods()")
	public void after(JoinPoint jp) {
		System.out.println("----------- AspectAdviceBeanUseAnnotation after 增强  for " + jp);
	}

	/*
	 * BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor
	 * InstantiationAwareBeanPostProcessor Bean实例创建前后 BeanPostProcessor
	 */
}

需要增强的目标类

@Component
public class BeanQ {

	public void do1(String task, int time) {
		System.out.println("-------------do1 do " + task + " time:" + time);
	}

	public String service1(String name) {
		System.out.println("-------------servce1 do " + name);
		return name;
	}

	public String service2(String name) {
		System.out.println("-------------servce2 do " + name);
		if (!"s1".equals(name)) {
			throw new IllegalArgumentException("参数 name != s1, name=" + name);
		}

		return name + " hello!";
	}
}

测试代码

@Configuration
@ComponentScan
public class AopMainAnno {
	public static void main(String[] args) {
		ApplicationContext context = new AnnotationConfigApplicationContext(AopMainAnno.class);
		BeanQ bq = context.getBean(BeanQ.class);
		bq.do1("task1", 20);
		System.out.println();

		bq.service1("service1");

		System.out.println();
		bq.service2("s1");
	}
}

执行即可看到增强的效果

1.2 @EnableAspectJAutoProxy

  需要使用代理增强处理,必须添加@EnableAspectJAutoProxy才生效。来看看他做了什么事情
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在registerOrEscalateApcAsRequired方法中会把上面的Java类注入到容器中。
在这里插入图片描述
所以我们需要看看 AnnotationAwareAspectJAutoProxyCreator 的结构

1.3 AnnotationAwareAspectJAutoProxyCreator

  直接来看类图结构,可以发现其本质就是一个 BeanPostProcessor ,只是扩展了更多的功能。
在这里插入图片描述
那么具体处理的逻辑

在这里插入图片描述

1.4 如何串联

  Bean的IoC是如何和对应的BeanPostProcessor串联的呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
isInfrastructureClass方法判断是否是基础设施
在这里插入图片描述
shouldSkip:是否应该跳过,会完成相关的advisor的收集
在这里插入图片描述
具体的处理流程

public List<Advisor> findAdvisorBeans() {
		// Determine list of advisor bean names, if not cached already.
		String[] advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the auto-proxy creator apply to them!
			// 获取当前BeanFactory中所有实现了Advisor接口的bean的名称
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		if (advisorNames.length == 0) {
			return new ArrayList<>();
		}

		// 对获取到的实现Advisor接口的bean的名称进行遍历
		List<Advisor> advisors = new ArrayList<>();
		// 循环所有的beanName,找出对应的增强方法
		for (String name : advisorNames) {
			// isEligibleBean()是提供的一个hook方法,用于子类对Advisor进行过滤,这里默认返回值都是true
			if (isEligibleBean(name)) {
				// 如果当前bean还在创建过程中,则略过,其创建完成之后会为其判断是否需要织入切面逻辑
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					if (logger.isTraceEnabled()) {
						logger.trace("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
					try {
						// 将当前bean添加到结果中
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					catch (BeanCreationException ex) {
						// 对获取过程中产生的异常进行封装
						Throwable rootCause = ex.getMostSpecificCause();
						if (rootCause instanceof BeanCurrentlyInCreationException) {
							BeanCreationException bce = (BeanCreationException) rootCause;
							String bceBeanName = bce.getBeanName();
							if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
								if (logger.isTraceEnabled()) {
									logger.trace("Skipping advisor '" + name +
											"' with dependency on currently created bean: " + ex.getMessage());
								}
								// Ignore: indicates a reference back to the bean we're trying to advise.
								// We want to find advisors other than the currently created bean itself.
								continue;
							}
						}
						throw ex;
					}
				}
			}
		}
		return advisors;
	}

2. 代理类的结构

  在上面的分析中出现了很多代理相关的代码,为了更好的理解,我们来梳理下Spring中的代理相关的结构

2.1 AopProxy

  在Spring中创建代理对象都是通过AopProxy这个接口的两个具体实现类来实现的,也就是jdk和cglib两种方式。
在这里插入图片描述

2.2 AopProxyFactory

  在Spring中通过AopProxyFactory这个工厂类来提供AopProxy。
在这里插入图片描述
默认的实现类是DefaultAopProxyFactory

	/**
	 * 真正的创建代理,判断一些列条件,有自定义的接口的就会创建jdk代理,否则就是cglib
	 * @param config the AOP configuration in the form of an
	 * AdvisedSupport object
	 * @return
	 * @throws AopConfigException
	 */
	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		// 这段代码用来判断选择哪种创建代理对象的方式
		// config.isOptimize()   是否对代理类的生成使用策略优化 其作用是和isProxyTargetClass是一样的 默认为false
		// config.isProxyTargetClass() 是否使用Cglib的方式创建代理对象 默认为false
		// hasNoUserSuppliedProxyInterfaces目标类是否有接口存在 且只有一个接口的时候接口类型不是SpringProxy类型
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			// 上面的三个方法有一个为true的话,则进入到这里
			// 从AdvisedSupport中获取目标类 类对象
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			// 判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
			// 如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			// 配置了使用Cglib进行动态代理或者目标类没有接口,那么使用Cglib的方式创建代理对象
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			// 使用JDK的提供的代理方式生成代理对象
			return new JdkDynamicAopProxy(config);
		}
	}
2.3 ProxyFactory

  ProxyFactory代理对象的工厂类,用来创建代理对象的工厂。
在这里插入图片描述
然后来看看 ProxyFactory的体系结构

在这里插入图片描述
ProxyConfig

这个类主要保存代理的信息,如果是否使用类代理,是否要暴露代理等。

public class ProxyConfig implements Serializable {

	/** use serialVersionUID from Spring 1.2 for interoperability. */
	private static final long serialVersionUID = -8409359707199703185L;

	// 是否代理的对象是类,动态代理分为代理接口和类,这里的属性默认是代理的接口
	private boolean proxyTargetClass = false;
	// 是否进行主动优化,默认是不会主动优化
	private boolean optimize = false;
	// 是否由此配置创建的代理不能被转成Advised类型,默认时候可转
	boolean opaque = false;
	// 是否会暴露代理在调用的时候,默认是不会暴露
	boolean exposeProxy = false;
	// 是否冻结此配置,不能被修改
	private boolean frozen = false;

}


Advised

由持有 AOP 代理工厂配置的类实现的接口。此配置包括拦截器和其他advice、advisor和代理接口。从 Spring 获得的任何 AOP 代理都可以转换为该接口,以允许操作其 AOP 通知。
在这里插入图片描述
AdvisedSupport

  • AOP代理配置管理器的基类。 此类的子类通常是工厂,从中可以直接获取 AOP 代理实例。此类可释放Advices和Advisor的内部管理子类,但实际上并没有实现代理创建方法,实现由子类提供
  • AdvisedSupport实现了Advised中处理Advisor和Advice的方法,添加Advice时会被包装成一个Advisor,默认使用的Advisor是DefaultPointcutAdvisor,DefaultPointcutAdvisor默认的Pointcut是TruePointcut(转换为一个匹配所有方法调用的Advisor与代理对象绑定)。
  • AdvisedSupport同时会缓存对于某一个方法对应的所有Advisor(Map<MethodCacheKey, List<Object>> methodCache),当Advice或Advisor发生变化时,会清空该缓存。getInterceptorsAndDynamicInterceptionAdvice用来获取对应代理方法对应有效的拦截器链 。

ProxyCreatorSupport

  继承了AdvisedSupport,ProxyCreatorSupport正是实现代理的创建方法,ProxyCreatorSupport有一个成员变量AopProxyFactory,而该变量的值默认是DefaultAopProxyFactory

在这里插入图片描述
这个也就和前面的AopProxyFactory串联起来了。

3. @Aspect解析

  然后我们分析下@Aspect注解的解析过程

	@Override
	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		// TODO: Consider optimization by caching the list of the aspect names
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor &&
					((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
				return true;
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}

先进入到shouldSkip方法。然后进入到 findCandidateAdvisors方法。

	/**
	 * 查找通知器
	 * @return
	 */
	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		// 找到系统中实现了Advisor接口的bean
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		if (this.aspectJAdvisorsBuilder != null) {
			// 找到系统中使用@Aspect标注的bean,并且找到该bean中使用@Before,@After等标注的方法,
			// 将这些方法封装为一个个Advisor
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

在这个方法中就可以看到@Aspect 注解的处理了,进入到buildAspectJAdvisors方法

	public List<Advisor> buildAspectJAdvisors() {
		// 获取切面名字列表
		List<String> aspectNames = this.aspectBeanNames;

		// 缓存字段aspectNames没有值,注意实例化第一个单实例bean的时候就会触发解析切面
		if (aspectNames == null) {
			// 双重检查
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					// 用于保存所有解析出来的Advisors集合对象
					List<Advisor> advisors = new ArrayList<>();
					// 用于保存切面的名称的集合
					aspectNames = new ArrayList<>();
					/**
					 * AOP功能中在这里传入的是Object对象,代表去容器中获取到所有的组件的名称,然后再
					 * 进行遍历,这个过程是十分的消耗性能的,所以说Spring会再这里加入了保存切面信息的缓存。
					 * 但是事务功能不一样,事务模块的功能是直接去容器中获取Advisor类型的,选择范围小,且不消耗性能。
					 * 所以Spring在事务模块中没有加入缓存来保存我们的事务相关的advisor
					 */
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					// 遍历我们从IOC容器中获取处的所有Bean的名称
					for (String beanName : beanNames) {
						// 判断当前bean是否为子类定制的需要过滤的bean
						if (!isEligibleBean(beanName)) {
							continue;
						}
						// We must be careful not to instantiate beans eagerly as in this case they
						// would be cached by the Spring container but would not have been weaved.
						// 通过beanName去容器中获取到对应class对象
						Class<?> beanType = this.beanFactory.getType(beanName, false);
						if (beanType == null) {
							continue;
						}
						// 判断当前bean是否使用了@Aspect注解进行标注
						if (this.advisorFactory.isAspect(beanType)) {
							aspectNames.add(beanName);
							// 对于使用了@Aspect注解标注的bean,将其封装为一个AspectMetadata类型。
							// 这里在封装的过程中会解析@Aspect注解上的参数指定的切面类型,如perthis
							// 和pertarget等。这些被解析的注解都会被封装到其perClausePointcut属性中
							AspectMetadata amd = new AspectMetadata(beanType, beanName);
							// 判断@Aspect注解中标注的是否为singleton类型,默认的切面类都是singleton类型
							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
								// 将BeanFactory和当前bean封装为MetadataAwareAspect-
								// InstanceFactory对象,这里会再次将@Aspect注解中的参数都封装
								// 为一个AspectMetadata,并且保存在该factory中
								MetadataAwareAspectInstanceFactory factory =
										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								// 通过封装的bean获取其Advice,如@Before,@After等等,并且将这些
								// Advice都解析并且封装为一个个的Advisor
								List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
								// 如果切面类是singleton类型,则将解析得到的Advisor进行缓存,
								// 否则将当前的factory进行缓存,以便再次获取时可以通过factory直接获取
								if (this.beanFactory.isSingleton(beanName)) {
									this.advisorsCache.put(beanName, classAdvisors);
								}
								else {
									this.aspectFactoryCache.put(beanName, factory);
								}
								advisors.addAll(classAdvisors);
							}
							else {
								// Per target or per this.
								// 如果@Aspect注解标注的是perthis和pertarget类型,说明当前切面
								// 不可能是单例的,因而这里判断其如果是单例的则抛出异常
								if (this.beanFactory.isSingleton(beanName)) {
									throw new IllegalArgumentException("Bean with name '" + beanName +
											"' is a singleton, but aspect instantiation model is not singleton");
								}
								// 将当前BeanFactory和切面bean封装为一个多例类型的Factory
								MetadataAwareAspectInstanceFactory factory =
										new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
								// 对当前bean和factory进行缓存
								this.aspectFactoryCache.put(beanName, factory);
								advisors.addAll(this.advisorFactory.getAdvisors(factory));
							}
						}
					}
					this.aspectBeanNames = aspectNames;
					return advisors;
				}
			}
		}

		if (aspectNames.isEmpty()) {
			return Collections.emptyList();
		}
		// 通过所有的aspectNames在缓存中获取切面对应的Advisor,这里如果是单例的,则直接从advisorsCache
		// 获取,如果是多例类型的,则通过MetadataAwareAspectInstanceFactory立即生成一个
		List<Advisor> advisors = new ArrayList<>();
		for (String aspectName : aspectNames) {
			List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
			// 如果是单例的Advisor bean,则直接添加到返回值列表中
			if (cachedAdvisors != null) {
				advisors.addAll(cachedAdvisors);
			}
			else {
				// 如果是多例的Advisor bean,则通过MetadataAwareAspectInstanceFactory生成
				MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
				advisors.addAll(this.advisorFactory.getAdvisors(factory));
			}
		}
		return advisors;
	}

然后看看 this.advisorFactory.getAdvisors(factory) 方法:完成 切入点表达式和对应Advice增强的方法绑定为Advisor。

	@Override
	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		// 获取标记为AspectJ的类
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		// 获取标记为AspectJ的name
		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
		// 对当前切面bean进行校验,主要是判断其切点是否为perflow或者是percflowbelow,Spring暂时不支持
		// 这两种类型的切点
		validate(aspectClass);

		// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
		// so that it will only instantiate once.
		// 将当前aspectInstanceFactory进行封装,这里LazySingletonAspectInstanceFactoryDecorator
		// 使用装饰器模式,主要是对获取到的切面实例进行了缓存,保证每次获取到的都是同一个切面实例
		MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
				new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

		List<Advisor> advisors = new ArrayList<>();
		// 这里getAdvisorMethods()会获取所有的没有使用@Pointcut注解标注的方法,然后对其进行遍历
		for (Method method : getAdvisorMethods(aspectClass)) {
			// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
			// to getAdvisor(...) to represent the "current position" in the declared methods list.
			// However, since Java 7 the "current position" is not valid since the JDK no longer
			// returns declared methods in the order in which they are declared in the source code.
			// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
			// discovered via reflection in order to support reliable advice ordering across JVM launches.
			// Specifically, a value of 0 aligns with the default value used in
			// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
			// 判断当前方法是否标注有@Before,@After或@Around等注解,如果标注了,则将其封装为一个Advisor
			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		// If it's a per target aspect, emit the dummy instantiating aspect.
		// 这里的isLazilyInstantiated()方法判断的是当前bean是否应该被延迟初始化,其主要是判断当前
		// 切面类是否为perthis,pertarget或pertypewithiin等声明的切面。因为这些类型所环绕的目标bean
		// 都是多例的,因而需要在运行时动态判断目标bean是否需要环绕当前的切面逻辑
		if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
			// 如果Advisor不为空,并且是需要延迟初始化的bean,则在第0位位置添加一个同步增强器,
			// 该同步增强器实际上就是一个BeforeAspect的Advisor
			Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
			advisors.add(0, instantiationAdvisor);
		}

		// Find introduction fields.
		// 判断属性上是否包含有@DeclareParents注解标注的需要新添加的属性,如果有,则将其封装为一个Advisor
		for (Field field : aspectClass.getDeclaredFields()) {
			Advisor advisor = getDeclareParentsAdvisor(field);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		return advisors;
	}

然后我们需要关注的方法 根据对应的方法获取对应的Advisor 通知。
在这里插入图片描述

	@Nullable
	public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
			int declarationOrderInAspect, String aspectName) {
		// 校验当前切面类是否使用了perflow或者percflowbelow标识的切点,Spring暂不支持这两种切点
		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

		// 获取当前方法中@Before,@After或者@Around等标注的注解,并且获取该注解的值,将其
		// 封装为一个AspectJExpressionPointcut对象
		AspectJExpressionPointcut expressionPointcut = getPointcut(
				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
		if (expressionPointcut == null) {
			return null;
		}

		// 将获取到的切点,切点方法等信息封装为一个Advisor对象,也就是说当前Advisor包含有所有
		// 当前切面进行环绕所需要的信息
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}

4. 多个切面的责任链实现

在这里插入图片描述
代理方法
在这里插入图片描述
invoke方法的处理

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;

		// 获取到我们的目标对象
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			// 若是equals方法不需要代理
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			// 若是hashCode方法不需要代理
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			// 若是DecoratingProxy也不要拦截器执行
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			// isAssignableFrom方法:如果调用这个方法的class或接口与参数cls表示的类或接口相同,或者是参数cls表示的类或接口的父类,则返回true
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;

			/**
			 * 这个配置是暴露我们的代理对象到线程变量中,需要搭配@EnableAspectJAutoProxy(exposeProxy = true)一起使用
			 * 比如在目标对象方法中再次获取代理对象可以使用这个AopContext.currentProxy()
			 * 还有的就是事务方法调用事务方法的时候也是用到这个
			 */
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				// 把我们的代理对象暴露到线程变量中
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			// 获取我们的目标对象
			target = targetSource.getTarget();
			// 获取我们目标对象的class
			Class<?> targetClass = (target != null ? target.getClass() : null);

			// Get the interception chain for this method.
			// 从Advised中根据方法名和目标类获取AOP拦截器执行链
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			// 如果拦截器链为空
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				// 通过反射直接调用执行
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				// 如果没有发现任何拦截器那么直接调用切点方法
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// We need to create a method invocation...
				// 将拦截器封装在ReflectiveMethodInvocation,以便于使用其proceed进行处理
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				// 执行拦截器链
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			// 获取返回类型
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			// 返回值类型错误
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
		finally {
			// 如果目标对象不为空且目标对象是可变的,如prototype类型
			// 通常我们的目标对象都是单例的,即targetSource.isStatic为true
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				// 释放目标对象
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				// 线程上下文复位
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

proceed方法

	/**
	 * 递归获取通知,然后执行
	 * @return
	 * @throws Throwable
	 */
	@Override
	@Nullable
	public Object proceed() throws Throwable {
		// We start with an index of -1 and increment early.
		// 从索引为-1的拦截器开始调用,并按序递增,如果拦截器链中的拦截器迭代调用完毕,开始调用target的函数,这个函数是通过反射机制完成的
		// 具体实现在AopUtils.invokeJoinpointUsingReflection方法中
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		// 获取下一个要执行的拦截器,沿着定义好的interceptorOrInterceptionAdvice链进行处理
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			// 这里对拦截器进行动态匹配的判断,这里是对pointcut触发进行匹配的地方,如果和定义的pointcut匹配,那么这个advice将会得到执行
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				// 如果不匹配,那么proceed会被递归调用,知道所有的拦截器都被运行过位置
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			// 普通拦截器,直接调用拦截器,将this作为参数传递以保证当前实例中调用链的执行
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

Spring源码分析-事务源码分析

一、事务的本质

1. 何为事务管理

  数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行

  事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。

  一个逻辑工作单元要成为事务,必须满足所谓的 ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
在这里插入图片描述

2. JDBC中的事务管理

  事务的本质我们还是要先来看下JDBC中对事务的处理。首先准备如下两张表[案例讲解以MYSQL为主]

-- MYSQL
CREATE TABLE t_user (
  id varchar(30) NOT NULL,
  user_name varchar(60) NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE t_log (
  id varchar(32) DEFAULT NULL,
  log varchar(20) DEFAULT NULL
);

  然后创建对应的实体对象

/**
 * 用户
 */
public class User implements Serializable {

	private static final long serialVersionUID = -5575893900970589345L;

	private String id;

	private String userName;

	public String getId() {
		return id;
	}

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

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
}

/**
 * 日志
 */
public class Log implements Serializable {

	private static final long serialVersionUID = -5575893900970589345L;

	private String id;

	private String log;

	public Log() {
	}

	public Log(String id, String log) {
		super();
		this.id = id;
		this.log = log;
	}

	public String getId() {
		return id;
	}

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

	public String getLog() {
		return log;
	}

	public void setLog(String log) {
		this.log = log;
	}

}

  然后我们通过JDBC操作来同时完成添加用户和添加日志的操作。

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            // 注册 JDBC 驱动
            // Class.forName("com.mysql.cj.jdbc.Driver");
            // 打开连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=UTC", "root", "123456");
            // 执行查询
            stmt = conn.createStatement();
            conn.setAutoCommit(false); // 关闭自动提交
            // 添加用户信息
            String sql = "INSERT INTO T_USER(id,user_name)values(1,'管理员')";
            stmt.executeUpdate(sql);
            // 添加日志问题
            sql = "INSET INTO t_log(id,log)values(1,'添加了用户:管理员')";
            stmt.executeUpdate(sql);
            conn.commit(); // 上面两个操作都没有问题就提交
        } catch (Exception e) {
            e.printStackTrace();
            // 出现问题就回滚
            try {
                conn.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        } finally {
            try {
                if (stmt != null) stmt.close();
            } catch (SQLException se2) {
            }
            try {
                if (conn != null) conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
    }

  通过上面的代码我们发下关键的操作有这三个:
在这里插入图片描述

3. Spring中的事务管理

  实际工作中我们更多的是结合Spring来做项目的这时我们要满足的情况是这种。
在这里插入图片描述
 从上图可以看出我们在Service中是可能调用多个Dao的方法来操作数据库中的数据的,我们要做的就是要保证UserService中的 addUser()方法中的相关操作满足事务的要求。在Spring中支持两种事务的使用方式

第一种基于配置文件的方式:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
	<!-- 开启扫描 -->
	<context:component-scan base-package="com.dpb.*"></context:component-scan>

	<!-- 配置数据源 -->
	<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<property name="username" value="pms"/>
		<property name="password" value="pms"/>
	</bean>

	<!-- 配置JdbcTemplate -->
	<bean class="org.springframework.jdbc.core.JdbcTemplate" >
		<constructor-arg name="dataSource" ref="dataSource"/>
	</bean>

	<!-- 
	Spring中,使用XML配置事务三大步骤:  
		1. 创建事务管理器  
		2. 配置事务方法  
		3. 配置AOP
	 -->
	 <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
	 	<property name="dataSource" ref="dataSource"/>
	 </bean>
	 <tx:advice id="advice" transaction-manager="transactionManager">
	 	<tx:attributes>
	 		<tx:method name="fun*" propagation="REQUIRED"/>
	 	</tx:attributes>
	 </tx:advice>
	 <!-- aop配置 -->
	 <aop:config>
		 <aop:pointcut expression="execution(* *..service.*.*(..))" id="tx"/>
	 	 <aop:advisor advice-ref="advice" pointcut-ref="tx"/>
	 </aop:config>
</beans>

第二种基于注解的使用方式:
在这里插入图片描述
但是我们需要先开启事务注解的方式。然后在对应的方法头部可以添加 @Transactional

	@Transactional
	public void insertUser(User u) {
		this.userDao.insert(u);
		Log log = new Log(System.currentTimeMillis() + "", System.currentTimeMillis() + "-" + u.getUserName());
		this.logDao.insert(log);
	}

当然上面的操作中涉及到了两个概念 事务的传播属性事务的隔离级别。参考这两篇文章

传播属性:https://blog.csdn.net/qq_38526573/article/details/87898161

隔离级别:https://blog.csdn.net/qq_38526573/article/details/87898730

二、Spring事务原理

  分析下Spring中事务这块的源码实现。

1.Spring事务的源码设计

1.1 事务管理器

  来看看事务管理器(PlatformTransactionManager).
在这里插入图片描述
TransactionManager:是顶级接口,里面是空的。

public interface TransactionManager {

}

PlatformTransactionManager:平台事务管理器

ReactiveTransactionManager:响应式编程的事务管理器

我们关注的重点是PlatformTransactionManager:

public interface PlatformTransactionManager extends TransactionManager {

	/**
            获取事务
	*/
	TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException;

	/**
	  提交数据
	 */
	void commit(TransactionStatus status) throws TransactionException;

	/**
	    回滚数据
	 */
	void rollback(TransactionStatus status) throws TransactionException;

}

PlatformTransactionManager也是个接口,在他下面的实现有两个比较重要实现
在这里插入图片描述
JtaTransactionManager:支持分布式事务【本身服务中的多数据源】

DataSourceTransactionManager:数据源事务管理器。在但数据源中的事务管理,这个是我们分析的重点。
在这里插入图片描述

1.2 事务定义

  然后在上面的 PlatformTransactoinManager中看到了 TransactionDefinition 这个对象,通过字面含义是 事务定义。来看看结构。
在这里插入图片描述
也就是 TransactionDefinition中定义了事务的 传播属性隔离级别,然后来看看具体的体系结构
在这里插入图片描述
在这里插入图片描述
DefaultTransactionDefinition:是事务定义的默认实现

DefaultTransactionAttribute:扩展了TransactionAttribute中的属性的实现

@Transactional:该组件就会被解析加载为对应的 TransactionDefinition对象。

在这里插入图片描述

1.3 事务的开启

  然后在 PlatformTransactionManager中获取事务的时候返回的是 TransactionStatus对象。来看看这个对象。
在这里插入图片描述
在这里插入图片描述
子类中扩展了
在这里插入图片描述

1.4 核心方法讲解

然后再看看核心的 getTransaction()方法

	/**
	 * This implementation handles propagation behavior. Delegates to
	 * {@code doGetTransaction}, {@code isExistingTransaction}
	 * and {@code doBegin}.
	 * @see #doGetTransaction
	 * @see #isExistingTransaction
	 * @see #doBegin
	 */
	@Override
	public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException {

		// Use defaults if no transaction definition given.
		// 如果没有事务定义信息则使用默认的事务管理器定义信息
		TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

		// 获取事务
		Object transaction = doGetTransaction();
		boolean debugEnabled = logger.isDebugEnabled();

		// 判断当前线程是否存在事务,判断依据为当前线程记录的连接不为空且连接中的transactionActive属性不为空
		if (isExistingTransaction(transaction)) {
			// Existing transaction found -> check propagation behavior to find out how to behave.
			// 当前线程已经存在事务
			return handleExistingTransaction(def, transaction, debugEnabled);
		}

		// Check definition settings for new transaction.
		// 事务超时设置验证
		if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
			throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
		}

		// No existing transaction found -> check propagation behavior to find out how to proceed.
		// 如果当前线程不存在事务,但是PropagationBehavior却被声明为PROPAGATION_MANDATORY抛出异常
		if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
			throw new IllegalTransactionStateException(
					"No existing transaction found for transaction marked with propagation 'mandatory'");
		}
		// PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED都需要新建事务
		else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
				def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			//没有当前事务的话,REQUIRED,REQUIRES_NEW,NESTED挂起的是空事务,然后创建一个新事务
			SuspendedResourcesHolder suspendedResources = suspend(null);
			if (debugEnabled) {
				logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
			}
			try {
				return startTransaction(def, transaction, debugEnabled, suspendedResources);
			}
			catch (RuntimeException | Error ex) {
				// 恢复挂起的事务
				resume(null, suspendedResources);
				throw ex;
			}
		}
		else {
			// Create "empty" transaction: no actual transaction, but potentially synchronization.
			// 创建一个空的事务
			if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
				logger.warn("Custom isolation level specified but no actual transaction initiated; " +
						"isolation level will effectively be ignored: " + def);
			}
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
		}
	}

关键的方法:doGetTransaction()方法

	/**
	 * 创建一个DataSourceTransactionObject当作事务,设置是否允许保存点,然后获取连接持有器ConnectionHolder
	 * 里面会存放JDBC的连接,设置给DataSourceTransactionObject,当然第一次是空的
	 *
	 * @return
	 */
	@Override
	protected Object doGetTransaction() {
		// 创建一个数据源事务对象
		DataSourceTransactionObject txObject = new DataSourceTransactionObject();
		// 是否允许当前事务设置保持点
		txObject.setSavepointAllowed(isNestedTransactionAllowed());
		/**
		 * TransactionSynchronizationManager 事务同步管理器对象(该类中都是局部线程变量)
		 * 用来保存当前事务的信息,我们第一次从这里去线程变量中获取 事务连接持有器对象 通过数据源为key去获取
		 * 由于第一次进来开始事务 我们的事务同步管理器中没有被存放.所以此时获取出来的conHolder为null
		 */
		ConnectionHolder conHolder =
				(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
		// 非新创建连接则写false
		txObject.setConnectionHolder(conHolder, false);
		// 返回事务对象
		return txObject;
	}

然后事务管理的代码

	/**
	 * Create a TransactionStatus for an existing transaction.
	 */
	private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {

		/**
		 * 判断当前的事务行为是不是PROPAGATION_NEVER的
		 * 表示为不支持事务,但是当前又存在一个事务,所以抛出异常
		 */
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}

		/**
		 * 判断当前的事务属性不支持事务,PROPAGATION_NOT_SUPPORTED,所以需要先挂起已经存在的事务
		 */
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction");
			}
			// 挂起当前事务
			Object suspendedResources = suspend(transaction);
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			// 创建一个新的非事务状态(保存了上一个存在事务状态的属性)
			return prepareTransactionStatus(
					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
		}

		/**
		 * 当前的事务属性状态是PROPAGATION_REQUIRES_NEW表示需要新开启一个事务状态
		 */
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
			if (debugEnabled) {
				logger.debug("Suspending current transaction, creating new transaction with name [" +
						definition.getName() + "]");
			}
			// 挂起当前事务并返回挂起的资源持有器
			SuspendedResourcesHolder suspendedResources = suspend(transaction);
			try {
				// 创建一个新的非事务状态(保存了上一个存在事务状态的属性)
				return startTransaction(definition, transaction, debugEnabled, suspendedResources);
			}
			catch (RuntimeException | Error beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
		}

		// 嵌套事务
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			// 不允许就报异常
			if (!isNestedTransactionAllowed()) {
				throw new NestedTransactionNotSupportedException(
						"Transaction manager does not allow nested transactions by default - " +
						"specify 'nestedTransactionAllowed' property with value 'true'");
			}
			if (debugEnabled) {
				logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
			}
			// 嵌套事务的处理
			if (useSavepointForNestedTransaction()) {
				// Create savepoint within existing Spring-managed transaction,
				// through the SavepointManager API implemented by TransactionStatus.
				// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
				// 如果没有可以使用保存点的方式控制事务回滚,那么在嵌入式事务的建立初始简历保存点
				DefaultTransactionStatus status =
						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
				// 为事务设置一个回退点
				status.createAndHoldSavepoint();
				return status;
			}
			else {
				// Nested transaction through nested begin and commit/rollback calls.
				// Usually only for JTA: Spring synchronization might get activated here
				// in case of a pre-existing JTA transaction.
				// 有些情况是不能使用保存点操作
				return startTransaction(definition, transaction, debugEnabled, null);
			}
		}

		// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
		if (debugEnabled) {
			logger.debug("Participating in existing transaction");
		}
		if (isValidateExistingTransaction()) {
			if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
				Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
				if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
					Constants isoConstants = DefaultTransactionDefinition.constants;
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] specifies isolation level which is incompatible with existing transaction: " +
							(currentIsolationLevel != null ?
									isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
									"(unknown)"));
				}
			}
			if (!definition.isReadOnly()) {
				if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
					throw new IllegalTransactionStateException("Participating transaction with definition [" +
							definition + "] is not marked as read-only but existing transaction is");
				}
			}
		}
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}

最后来看看 startTransaction() 方法

	/**
	 * Start a new transaction.
	 */
	private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
			boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

		// 是否需要新同步
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		// 创建新的事务
		DefaultTransactionStatus status = newTransactionStatus(
				definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
		// 开启事务和连接
		doBegin(transaction, definition);
		// 新同步事务的设置,针对于当前线程的设置
		prepareSynchronization(status, definition);
		return status;
	}

doBegin方法开启和连接事务

	@Override
	protected void doBegin(Object transaction, TransactionDefinition definition) {
		// 强制转化事务对象
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		Connection con = null;

		try {
			// 判断事务对象没有数据库连接持有器
			if (!txObject.hasConnectionHolder() ||
					txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
				// 通过数据源获取一个数据库连接对象
				Connection newCon = obtainDataSource().getConnection();
				if (logger.isDebugEnabled()) {
					logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
				}
				// 把我们的数据库连接包装成一个ConnectionHolder对象 然后设置到我们的txObject对象中去
				txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
			}

			// 标记当前的连接是一个同步事务
			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
			con = txObject.getConnectionHolder().getConnection();

			// 为当前的事务设置隔离级别
			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
			// 设置先前隔离级别
			txObject.setPreviousIsolationLevel(previousIsolationLevel);
			// 设置是否只读
			txObject.setReadOnly(definition.isReadOnly());

			// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
			// so we don't want to do it unnecessarily (for example if we've explicitly
			// configured the connection pool to set it already).
			// 关闭自动提交
			if (con.getAutoCommit()) {
				//设置需要恢复自动提交
				txObject.setMustRestoreAutoCommit(true);
				if (logger.isDebugEnabled()) {
					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
				}
				// 关闭自动提交
				con.setAutoCommit(false);
			}

			// 判断事务是否需要设置为只读事务
			prepareTransactionalConnection(con, definition);
			// 标记激活事务
			txObject.getConnectionHolder().setTransactionActive(true);

			// 设置事务超时时间
			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
			}

			// Bind the connection holder to the thread.
			// 绑定我们的数据源和连接到我们的同步管理器上,把数据源作为key,数据库连接作为value 设置到线程变量中
			if (txObject.isNewConnectionHolder()) {
				// 将当前获取到的连接绑定到当前线程
				TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
			}
		}

		catch (Throwable ex) {
			if (txObject.isNewConnectionHolder()) {
				// 释放数据库连接
				DataSourceUtils.releaseConnection(con, obtainDataSource());
				txObject.setConnectionHolder(null, false);
			}
			throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
		}
	}

在doBegin方法中核心的关闭了自动提交

在这里插入图片描述
同时把连接绑定到本地线程中bindResource方法
在这里插入图片描述

2.Spring事务源码串联

2.1 编程式事务

  结合上面的设计,就可以来实现事务的处理了

@Autowired
	private UserDao userDao;

	@Autowired
	private PlatformTransactionManager txManager;

	@Autowired
	private LogService logService;

	@Transactional
	public void insertUser(User u) {

		// 1、创建事务定义
		DefaultTransactionDefinition definition = new DefaultTransactionDefinition();

		// 2、根据定义开启事务
		TransactionStatus status = txManager.getTransaction(definition);

		try {
			this.userDao.insert(u);
			Log log = new Log(System.currentTimeMillis() + "", System.currentTimeMillis() + "-" + u.getUserName());
			// this.doAddUser(u);
			this.logService.insertLog(log);
			// 3、提交事务
			txManager.commit(status);
		} catch (Exception e) {
			// 4、异常了,回滚事务
			txManager.rollback(status);
			throw e;
		}
	}
2.2 AOP事务

  上面的案例代码可以看到在Service中我们通过事务处理的代码实现了事务管理,同时结合AOP的内容,发现完全可以把事务的代码抽取出来,然后来看看Spring中这块是如何处理的。
在这里插入图片描述
可以通过Debug的方式看到处理的关键流程 TransactionInterceptor 就是事务处理的 advice

	@Override
	@Nullable
	public Object invoke(MethodInvocation invocation) throws Throwable {
		// Work out the target class: may be {@code null}.
		// The TransactionAttributeSource should be passed the target class
		// as well as the method, which may be from an interface.
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}

进入到invokeWithinTransaction方法中

	@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		// 获取我们的事务属性源对象
		TransactionAttributeSource tas = getTransactionAttributeSource();
		// 通过事务属性源对象获取到当前方法的事务属性信息
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		// 获取我们配置的事务管理器对象
		final TransactionManager tm = determineTransactionManager(txAttr);

		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
				if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
					throw new TransactionUsageException(
							"Unsupported annotated transaction on suspending function detected: " + method +
							". Use TransactionalOperator.transactional extensions instead.");
				}
				ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
				if (adapter == null) {
					throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
							method.getReturnType());
				}
				return new ReactiveTransactionSupport(adapter);
			});
			return txSupport.invokeWithinTransaction(
					method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
		}

		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		// 获取连接点的唯一标识  类名+方法名
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		// 声明式事务处理
		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			// 创建TransactionInfo
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				// 执行被增强方法,调用具体的处理逻辑
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				// 异常回滚
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				//清除事务信息,恢复线程私有的老的事务信息
				cleanupTransactionInfo(txInfo);
			}

			if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				// Set rollback-only in case of Vavr failure matching our rollback rules...
				TransactionStatus status = txInfo.getTransactionStatus();

				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}

			//成功后提交,会进行资源储量,连接释放,恢复挂起事务等操作
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			// 编程式事务处理
			Object result;
			final ThrowableHolder throwableHolder = new ThrowableHolder();

			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
					TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
					try {
						Object retVal = invocation.proceedWithInvocation();
						if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
							// Set rollback-only in case of Vavr failure matching our rollback rules...
							retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
						}
						return retVal;
					}
					catch (Throwable ex) {
						if (txAttr.rollbackOn(ex)) {
							// A RuntimeException: will lead to a rollback.
							if (ex instanceof RuntimeException) {
								throw (RuntimeException) ex;
							}
							else {
								throw new ThrowableHolderException(ex);
							}
						}
						else {
							// A normal return value: will lead to a commit.
							throwableHolder.throwable = ex;
							return null;
						}
					}
					finally {
						cleanupTransactionInfo(txInfo);
					}
				});
			}
			catch (ThrowableHolderException ex) {
				throw ex.getCause();
			}
			catch (TransactionSystemException ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
					ex2.initApplicationException(throwableHolder.throwable);
				}
				throw ex2;
			}
			catch (Throwable ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
				}
				throw ex2;
			}

			// Check result state: It might indicate a Throwable to rethrow.
			if (throwableHolder.throwable != null) {
				throw throwableHolder.throwable;
			}
			return result;
		}
	}

然后进入到createTransactionIfNecessary方法中
在这里插入图片描述
在这里插入图片描述
然后进入 getTransaction 这个方法我们前面看过
在这里插入图片描述
在这里插入图片描述
核心的是doBegin方法。完成 自动提交的关闭和 本地线程 对象的存储
在这里插入图片描述

2.3 TransactionInterceptor

  接下来看看TransactionInterceptor是如何注入到容器中的,首先来看看事务的开启@EnableTransactionManagement
在这里插入图片描述
在这里插入图片描述
一步步进入
在这里插入图片描述
在这里插入图片描述
可以看到对应的拦截器的注入
在这里插入图片描述
然后可以看到拦截器关联到了Advisor中了
在这里插入图片描述


事务传播行为

所谓的事务传播行为就是说多个声明的事务方法,相互调用时,事务该如何传递

例子
在这里插入图片描述
Spring的7种事务传播行为
Require(默认) 判断传播过程中是否存在事务,不存在则开启一个新的事务
Require_New 不管是否存在事务,都会开启一个新的事务,各事务之间是相互独立的,外部事务抛异常是不会影响内部事务的一个正常提交的
Nested 当前存在事务就嵌套执行,没有事务则新建一个事务,类似Require_New 的传播行为
Supports 支持当前事务,如果当前不存在事务,则以非事务的方式执行
Not_Supported 以非事务的方式执行,如果当前存在事务,则将事务挂起
Mandatory 强制的事务执行,如果不存在事务则抛出异常
Never 以非事务的方式执行,如果当前存在事务则抛异常

除非是嵌套事务的情况下,否则无需关注

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 源码分析是一个相对复杂和庞大的话题,无法在一次对话中详细讨论。不过,我可以给你提供一些关于 Spring 源码分析的一般指导和建议。 1. 了解 Spring 的核心模块:Spring 框架是模块化的,每个模块都有不同的功能和职责。在开始源码分析之前,你需要先了解 Spring 的核心模块,如 Spring Core、Spring MVC、Spring Data 等。 2. 阅读官方文档和源码注释:Spring 框架的官方文档和源码注释是你学习和理解源码的重要资源。官方文档提供了对 Spring 各个模块的详细说明,源码注释则解释了代码的作用和实现细节。 3. 调试和跟踪代码:在进行源码分析时,调试器是你的好帮手。通过设置断点、单步跟踪以及观察变量的值,你可以深入理解代码的执行流程和逻辑。 4. 理解设计模式和原理:Spring 框架采用了许多设计模式和原理来实现其功能。在分析源码时,你需要熟悉这些设计模式和原理,例如依赖注入、AOP、工厂模式等。 5. 参考开源社区和博客:Spring 框架是一个非常活跃的开源社区,许多开发者在博客和论坛上分享了他们的源码分析和理解。阅读这些文章可以帮助你更好地理解 Spring 框架的实现细节。 请记住,深入分析 Spring 源码需要耐心和时间投入,同时也需要有一定的 Java 和设计模式的基础。希望这些指导对你有所帮助!如果你有具体的问题或者需要更详细的信息,欢迎继续提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值