Demonstration of Spring's IOC dependency processing method

Foreword: Spring can automatically handle loading dependent beans when getting Bean, that is, first instantiate and initialize dependent beans, and then instantiate this bean. How to deal with the verification of dependencies and circular dependencies in this process, we use a small Case presentation.

1 Overview

We make a self-made BeanFacotry that integrates a series of functions such as BeanDefinition registration, bean instantiation, dependency verification and dependency registration, which is based on the integrated BeanFaoctry ( DefaultListableBeanFactory ) that inherits the functions of various interfaces from spring . First of all, this BeanFactory needs to have a container that can store Beandifitions. Like spring, we use a Map to install BeanDefition. In addition, this BeanFacotry needs another Map container to install the dependencies of beans. We use Map<String, Set<String>> storage.

    BeanDefinition mainly has several attributes. One name is the id of the registered bean, one is the list collection that relies on the name of the Bean, and the other is the instance of the Bean (if the instance is created, it is not null).

class BeanDefinition {
	private Bean bean; // bean初始化后
	private String name; // 和id一致,并且创建bean的时候,设置成
	private String[] dependsOn; // 此bean的依赖的名称

    The Bean obtained by spring is an Object type. We use a fixed Pojo Bean instead of simplifying it. It is also very simple, just a name attribute (consistent with the id of BeanDefinition) and a list of dependent beans.

class Bean {
    private String name;
    private List<Bean> list = new ArrayList<>(); // 引用的bean

  2. The function of DefaultListableBeanFactory

1) The function of registering and acquiring Beandifition, that is, storing Beandifition in the internal map, and the acquisition is also taken from the map according to the id.

        public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
    
        public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
            BeanDefinition bd = this.beanDefinitionMap.get(beanName);
            return bd;
        }

2) Verify dependencies and store dependencies.

The verification dependency is the Bean we want to create. When we need to find its dependencies, create these dependencies. If these dependencies also depend on the Bean to be created, then this will have a circular dependency. (Currently-dependent first getBean- The dependency of the dependency is current-current getBean...).

Since we mainly store which classes the current class depends on in the BeanDefinition, and when verifying, we need to know which classes the current class is dependent on. This requires registering which classes the current class depends on to the BeanFactory.

/**
		 * 注册beanName被那个依赖
		 */
		public void registerDependentBean(String beanName, String dependentBeanName) {
			Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
			if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
				return;
			}
			synchronized (this.dependentBeanMap) {
				dependentBeans = this.dependentBeanMap.get(beanName);
				if (dependentBeans == null) {
					dependentBeans = new LinkedHashSet<String>(8);
					this.dependentBeanMap.put(beanName, dependentBeans);
				}
				dependentBeans.add(dependentBeanName);
			}
		}
	
		/**
		 * 判断是否依赖: beanName是否是dependsOnBean的依赖
		 */
		protected boolean isDependent(String beanName, String dependentBeanName) {
			return isDependent(beanName, dependentBeanName, null);
		}
	
		private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
			if (alreadySeen == null) {
				alreadySeen = new HashSet<String>();
			}
			if (alreadySeen.contains(beanName)) {
				return false;
			}
			Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
			if (dependentBeans == null) {
				return false;
			}
			if (dependentBeans.contains(dependentBeanName)) {
				return true;
			}
			for (String transitiveDependency : dependentBeans) { // beanName被依赖的bean是否dependentBeanName
				alreadySeen.add(beanName);
				if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
					return true;
				}
			}
			return false;
		}

3) Get Bean and other functions The
        getBean series function will return when there is a bean, if it is not created, depend on processing and other detailed operations, we will simply handle it according to the method name in spring. From the doGetBean method, if the bean has been created, return directly. If there is a dependency, first perform the getBean operation on the dependent bean, which checks the circular dependency to ensure that the dependency of the bean to be created is created before the method is created. .

public Bean getBean(String name) {
			return doGetBean(name);
		}
	
		private Bean doGetBean(String beanName) {
			BeanDefinition bd = getBeanDefinition(beanName);
			if (bd != null && bd.getBean() != null) {
				return bd.getBean();
			}
			String[] dependsOn = bd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) { // dependsOnBean本身是beanName依赖
					if (isDependent(beanName, dependsOnBean)) { // beanName是dependsOnBean依赖
						throw new BeanCreationException("循环依赖...");
					}
					registerDependentBean(dependsOnBean, beanName);
					getBean(dependsOnBean);
				}
			}
			return createBean(beanName, bd);
		}
	
		/**当前bean创建时,依赖的bean,一定创建好了,直接set进去即可。 */
		private Bean createBean(String name, BeanDefinition bd) {
			Bean bean = new Bean();
			bean.setName(name);
			bd.setBean(bean);
			String[] dependsOn = bd.getDependsOn();
			if (dependsOn != null) {
				for (String depend : dependsOn) {
					BeanDefinition beanDefinition = getBeanDefinition(depend);
					Bean dependBean = beanDefinition.getBean();
					if (dependBean != null) {
						bean.getList().add(dependBean);
					}
				}
			}
			return bean;
		}

3. Test

public static void main(String[] args) throws Exception {
			BeanDefinition root = new BeanDefinition("Root");
			BeanDefinition child = new BeanDefinition("Child");
			root.setDependsOn(new String[] { child.getName() });
			// child.setDependsOn(new String[]{root.getName()}); // 如果不注释就是循环引用!!!
			DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
			factory.registerBeanDefinition(root.getName(), root);
			factory.registerBeanDefinition(child.getName(), child);
			factory.preInstantiateSingletons();
			Bean bean1 = factory.getBean(root.getName());
			System.out.println(bean1);
		}

    4, complete demo

 

/**
 * Spring的IOC依赖的处理方式的演示
 */
public class Dependence {

	public static void main(String[] args) throws Exception {
		BeanDefinition root = new BeanDefinition("Root");
		BeanDefinition child = new BeanDefinition("Child");
		root.setDependsOn(new String[] { child.getName() });
		// child.setDependsOn(new String[]{root.getName()}); // 如果不注释就是循环引用!!!
		DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
		factory.registerBeanDefinition(root.getName(), root);
		factory.registerBeanDefinition(child.getName(), child);
		factory.preInstantiateSingletons();
		Bean bean1 = factory.getBean(root.getName());
		System.out.println(bean1);
	}

}

/**
 * 综合了各个层级BeanFactory的能力的类
 */
class DefaultListableBeanFactory {

	/**
	 * 装bean的定义
	 */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

	/**
	 * 装key的BeanDefinition被哪些依赖
	 */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
		this.beanDefinitionMap.put(beanName, beanDefinition);
	}

	public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
		BeanDefinition bd = this.beanDefinitionMap.get(beanName);
		return bd;
	}

	/**
	 * 注册beanName被那个依赖
	 */
	public void registerDependentBean(String beanName, String dependentBeanName) {
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
			return;
		}
		synchronized (this.dependentBeanMap) {
			dependentBeans = this.dependentBeanMap.get(beanName);
			if (dependentBeans == null) {
				dependentBeans = new LinkedHashSet<String>(8);
				this.dependentBeanMap.put(beanName, dependentBeans);
			}
			dependentBeans.add(dependentBeanName);
		}
	}

	/**
	 * 判断是否依赖: beanName是否是dependsOnBean的依赖
	 */
	protected boolean isDependent(String beanName, String dependentBeanName) {
		return isDependent(beanName, dependentBeanName, null);
	}

	private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
		if (alreadySeen == null) {
			alreadySeen = new HashSet<String>();
		}
		if (alreadySeen.contains(beanName)) {
			return false;
		}
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		if (dependentBeans == null) {
			return false;
		}
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		for (String transitiveDependency : dependentBeans) { // beanName被依赖的bean是否dependentBeanName
			alreadySeen.add(beanName);
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 实例化所有的单例bean
	 */
	public void preInstantiateSingletons() throws Exception {
		for (String benaName : beanDefinitionMap.keySet()) {
			getBean(benaName);
		}
	}

	public Bean getBean(String name) {
		return doGetBean(name);
	}

	private Bean doGetBean(String beanName) {
		BeanDefinition bd = getBeanDefinition(beanName);
		if (bd != null && bd.getBean() != null) {
			return bd.getBean();
		}
		String[] dependsOn = bd.getDependsOn();
		if (dependsOn != null) {
			for (String dependsOnBean : dependsOn) { // dependsOnBean本身是beanName依赖
				if (isDependent(beanName, dependsOnBean)) { // beanName是dependsOnBean依赖
					throw new BeanCreationException("循环依赖...");
				}
				registerDependentBean(dependsOnBean, beanName);
				getBean(dependsOnBean);
			}
		}
		return createBean(beanName, bd);
	}

	/**
	 * 当前bean创建时,依赖的bean,一定创建好了,直接set进去即可。
	 */
	private Bean createBean(String name, BeanDefinition bd) {
		Bean bean = new Bean();
		bean.setName(name);
		bd.setBean(bean);
		String[] dependsOn = bd.getDependsOn();
		if (dependsOn != null) {
			for (String depend : dependsOn) {
				BeanDefinition beanDefinition = getBeanDefinition(depend);
				Bean dependBean = beanDefinition.getBean();
				if (dependBean != null) {
					bean.getList().add(dependBean);
				}
			}
		}
		return bean;
	}
}

/**
 * Bean
 */
class Bean {
	private String name;
	private List<Bean> list = new ArrayList<>(); // 引用的bean

	public List<Bean> getList() {
		return list;
	}

	public void setList(List<Bean> list) {
		this.list = list;
	}

	public String getName() {
		return name;
	}

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

	@Override
	public String toString() {
		return "Bean [name=" + name + ", list=" + list + "]";
	}
}

/**
 * BeanDefinition的定义
 */
class BeanDefinition {
	private Bean bean; // bean初始化后
	private String name; // 和id一致,并且创建bean的时候,设置成
	private String[] dependsOn; // 此bean的依赖的名称

	public String getName() {
		return name;
	}

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

	public String[] getDependsOn() {
		return dependsOn;
	}

	public void setDependsOn(String[] dependsOn) {
		this.dependsOn = dependsOn;
	}

	public BeanDefinition(String name) {
		super();
		this.name = name;
	}

	public Bean getBean() {
		return bean;
	}

	public void setBean(Bean bean) {
		this.bean = bean;
	}
}

 

 

 

Guess you like

Origin blog.csdn.net/shuixiou1/article/details/113406879