天天看点

Spring 依赖注入——模拟实现(二)(方法注入)

Spring 依赖注入——模拟实现(二)(方法注入)

        这里紧接着上一篇,Spring 依赖注入——模拟实现(一)(对象注入)着重讲述如解决类似jar包里面的我们无法增加注解的类。

难点一

        怎样获取无法加注解的类?

解决思路

        1.给方法加Bean注解。

@Bean
	public Point getPoint(Complex complex) {
		Point point = new Point(complex);
		return point;
	}
           

        2.通过包扫描,扫描带有Component注解的类,再进一步扫描该类里面带有Bean注解的方法,并且执行该方法,把方法返回值作为BeanDefinition的object,键为返回值类型的名称,增加到beanPool里面。

        在包扫描时,先处理带有Component注解的类,并收集相应带有Bean注解的方法(这里不能马上执行,因为若该方法里面需要有带有Component注解的类的实例为参数的话,如果在方法执行时,参数要求未能达到,那么该方法不能执行,或者报错),再去处理带有Bean注解的方法。

类设计

        为了更好的描述这个方法,我们设计了BeanmethodDefinition类,里面封装了被Bean注解的方法的的元数据类,实例,方法,以及参数个数。具体内容如下。

package com.mec.spring_imitate.core;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;

public class BeanMethodDefinition {
	private Class<?> klass;
	private Object object;
	private Method method;
	private int parameterCount;

	BeanMethodDefinition() {
	}

	Class<?> getKlass() {
		return klass;
	}

	void setKlass(Class<?> klass) {
		this.klass = klass;
	}

	Object getObject() {
		return object;
	}

	void setObject(Object object) {
		this.object = object;
	}

	Method getMethod() {
		return method;
	}

	void setMethod(Method method) {
		this.method = method;
		Parameter[] parameters = method.getParameters();
		if (parameters.length <= 0) {
			parameterCount = 0;
			return;
		}
		
		Map<Class<?>, Object> paraTypeMap = new HashMap<Class<?>, Object>();
		for (Parameter parameter : parameters) {
			paraTypeMap.put(parameter.getType(), null);
		}
		parameterCount = paraTypeMap.size();
	}

	int getParameterCount() {
		return parameterCount;
	}

	int decrease() {
		return --this.parameterCount;
	}

}

           

难点二

        如何处理处理次序及循环依赖问题?

@Bean
	public Point getPoint(Complex complex) {
		Point point = new Point(complex);
		return point;
	}
           

        比如,图示方法中(假如该方法是在Configuration类(该类带有Conponent注解)里面的),需要Complex的一个实例作为参数,如果该参数是带有Component注解的,并且已经通过包扫描形成BeanDefinition加入到BeanFactory里面的Map,即beanPool里面,那么它是符合我们的期望的。

        但如果是先扫描的是Configuration类呢(比如,当Configuration类所在包比Complex类所在包较浅时)?那么悲剧发生了,此时该方法里面的参数都不存在,所以此刻必须先押后处理。

        一个简单的方案是,用一个List来收集 BeanMethodDefinition,收集了之后,再一个个判断,看能否执行,如果能执行,则执行,否则继续等待,但是,用这种方式,到底应该执行多少遍,才能执行完所有的方法呢?如果只要没执行完,就重新扫描,那么,重新扫描的依据又是什么?更可怕的是,如果某一BeanMethodDefinition不存在,而在另一扫描包内扫描才能形成。那么,就执行不下去了。

        其二,当被注解的方法所需参数需要的有多个(极有可能来自于BeanFactory里面的beanPool),那么当参数不全时又该当如何处理?

解决思路

        2.在方法和参数之间形成一种依赖或者是映射关系,以便更好的描述及处理这种关系。当通过包扫描处理完Component注解的类时,对于收集到的带有Bean注解的方法,我们在类

ParameterDependance

中形成方法与参数的映射关系表

Map<Class<?>, List<BeanMethodDefinition>> parameterDependance

,对于已经满足了相关参数要求(及所需要的参数已经加入到BeanFactory里面的beanPool里面)的方法,提取出去,放到类

OnReadyBeanMethodDefinition

中的可执行列表

List<BeanMethodDefinition> onReadymethodDefinitionList

里面,执行,并且每次执行都会产生一个新的BeanDefinition加入到BeanFactory里面的beanPool里面,那么,对于那些需要以此BeanDefinition为参数的BeanMethodDefinition,当参数要求得到满足时,又可以提取出去到

onReadymethodDefinitionList

,执行,又形成新的BeanDefinition加入到beanPool里面,如此往复,来解决处理次序及循环依赖问题。

        对于那些参数要求始终不能满足的,这里我们报出运行时异常,告知使用者,哪些参数不存在。

        这里需要重新设计一下BeanMethodDefinition类,我给其加了parameterCount成员及相关方法,更改以后的BeanMethodDefinition类具体内容如下图所示。

package com.mec.spring_imitate.core;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;

public class BeanMethodDefinition {
	private Class<?> klass;
	private Object object;
	private Method method;
	private int parameterCount;

	BeanMethodDefinition() {
	}

	Class<?> getKlass() {
		return klass;
	}

	void setKlass(Class<?> klass) {
		this.klass = klass;
	}

	Object getObject() {
		return object;
	}

	void setObject(Object object) {
		this.object = object;
	}

	Method getMethod() {
		return method;
	}

	void setMethod(Method method) {
		this.method = method;
		Parameter[] parameters = method.getParameters();
		if (parameters.length <= 0) {
			parameterCount = 0;
			return;
		}
		
		Map<Class<?>, Object> paraTypeMap = new HashMap<Class<?>, Object>();
		for (Parameter parameter : parameters) {
			paraTypeMap.put(parameter.getType(), null);
		}
		parameterCount = paraTypeMap.size();
	}

	int getParameterCount() {
		return parameterCount;
	}

	int decrease() {
		return --this.parameterCount;
	}

}

           

        增加parameterCount成员是用来表示被Bean注解标识的方法的参数个数的,使得BeanMethodDefinition类更加完整,以便后续操作。已下给出简单说明。

ClassTwo fun1(Point point);
ClassOne fun2(Comlex complex,Point point);
ClassThree fun3();

           
Spring 依赖注入——模拟实现(二)(方法注入)

        如上图所示,以参数类类型为键,及需要该参数的函数对应的BeanMethodDefinition列表为值,对于函数fun1来说,则需要一个参数Point.class,parameterCount=1;对于函数fun2来说需要两个参数Complex和Point.class,parameterCount=2;对于函数fun3来说,它是一个无参函数,parameterCount=0,所以无需参数即能执行。

        这里我们是这样来进行设计的,在映射关系表

parameterDependance

中,当某一参数已经满足时,将它对应的BeanMethodDefinition列表里面的所有BeanMethodDefinition的parameterCount-1(如果某个BeanMethodDefinition的parameterCount等于0,则说明所需参数已全部就位,则将其加入到

onReadymethodDefinitionList

),并删除

parameterDependance

里面该参数类类型所对应的BeanMethodDefinition列表。

        比如,当Point.class参数已经满足时,先将对应列表里面的所有BeanMethodDefinition1,BeanMethodDefinition2的parameterCount减一,并且删除BeanMethodDefinition1,BeanMethodDefinition2,此时,BeanMethodDefinition1的parameterCount值为0,BeanMethodDefinition2的parameterCount值为1,则将BeanMethodDefinition1往

onReadymethodDefinitionList

里面加,执行,执行过后再次检查

parameterDependance

中是否有新的映射关系得到满足,有的话则重复上述操作,直到

parameterDependance

里面只剩下那些相关参数无法被满足的函数的映射关系,此时,报出异常,指出函数因哪些参数未得到满足而不能执行。

更新后的类BeanFactory 具体内容如下图所示。

package com.mec.spring_imitate.core;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;

import com.mec.orm.core.PackageScanner;
import com.mec.spring_imitate.annotation.Autowired;
import com.mec.spring_imitate.annotation.Bean;
import com.mec.spring_imitate.annotation.Component;

public class BeanFactory {
	private static final Map<String, BeanDefinition> beanPool;
	static {
		beanPool = new HashMap<String, BeanDefinition>();
	}
	private static boolean firstGetBean = true;
	
	public BeanFactory() {
	}
	
	boolean isFirstGetBean() {
		return firstGetBean;
	}

	void setFirstGetBean(boolean firstGetBean) {
		BeanFactory.firstGetBean = firstGetBean;
	}

	public void scanBeanByPackage(String packageName) {
		OnReadyBeanMethodDefinition orbmd = new OnReadyBeanMethodDefinition();
		ParameterDependance parameterDependance = new ParameterDependance();
		
		new PackageScanner() {
			@Override
			public void dealClass(Class<?> klass) {
				if (klass.isPrimitive()
						|| klass.isInterface()
						|| klass.isAnnotation()
						|| klass.isEnum()
						|| klass.isArray()
						|| !klass.isAnnotationPresent(Component.class)) {
					return;
				}
				
				Object object = null;
				try {
					object = klass.newInstance();
					BeanDefinition bd = new BeanDefinition();
					bd.setKlass(klass);
					bd.setObject(object);
					
					beanPool.put(klass.getName(), bd);
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				
				// 查找并处理Bean注解的方法
				// 现在只能将所有Bean注解的方法收集起来
				collectBeanMethod(klass, object, orbmd);
			}
		}.packageScanner(packageName);

		// 现在开始检查参数方法映射表里面的方法是否满足参数要求
		parameterDependance.checkOnReady(orbmd);
		// 现在开始处理Bean注解的方法
		processBeanMethod(parameterDependance, orbmd);
	}
	//根据方法取得方法参数对应的具体类型的值
	private Object[] getParameterValue(Method method) {
		Parameter[] parameters = method.getParameters();
		int paraCount = parameters.length;
		if (paraCount <= 0) {
			return new Object[] {};
		}
		
		Object[] parameterValues = new Object[paraCount];
		int index = 0;
		for (Parameter parameter : parameters) {
			Class<?> type = parameter.getType();
			parameterValues[index++] = getBeanDefinition(type).getObject();
		}
		
		return parameterValues;
	}
	//收集带有Bean注解的方法,形成对应的BeanMethodDefinition,并判断是否可以加入到往参数方法映射表里面
	private static void collectBeanMethod(Class<?> klass, Object object, 
			OnReadyBeanMethodDefinition orbmd) {
		ParameterDependance pd = new ParameterDependance();
		
		Method[] methods = klass.getDeclaredMethods();
		for (Method method : methods) {
			if (!method.isAnnotationPresent(Bean.class)) {
				continue;
			}
			BeanMethodDefinition bmd = new BeanMethodDefinition();
			bmd.setKlass(klass);
			bmd.setObject(object);
			bmd.setMethod(method);
			
			if (pd.addDependance(bmd) == false) {
				orbmd.in(bmd);
			}
		}
	}
	//开始执行准备列表或者说可执行列表里面的BeanMethodDefinition
	private void processBeanMethod(
			ParameterDependance parameterDependance, 
			OnReadyBeanMethodDefinition orbmd) {
		//可执行列表里面的BeanMethodDefinition没执行完
		while (orbmd.hasNext()) {
			BeanMethodDefinition bmd = orbmd.next();
			Object object = bmd.getObject();
			Method method = bmd.getMethod();
			Object[] parameterValues = getParameterValue(method);
			
			try {//反射机制调用执行
				Object result = method.invoke(object, parameterValues);
				//方法返回值形成新的BeanDefinition加入到beanPool里面
				Class<?> resultClass = result.getClass();
				BeanDefinition beanDefinition = new BeanDefinition();
				beanDefinition.setInject(true);
				beanDefinition.setKlass(resultClass);
				beanDefinition.setObject(result);
				beanPool.put(resultClass.getName(), beanDefinition);
				//重新匹配参数方法依赖表
				parameterDependance.matchDependance(resultClass, orbmd);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	
	boolean hasClass(String className) {
		return beanPool.containsKey(className);
	}
	
	BeanDefinition getBeanDefinition(String klassName) {
		return beanPool.get(klassName);
	}
	
	BeanDefinition getBeanDefinition(Class<?> klass) {
		return getBeanDefinition(klass.getName());
	}

	private void injectProperties(BeanDefinition beanDefinition) throws RuntimeException {
		Class<?> klass = beanDefinition.getKlass();
		Object object = beanDefinition.getObject();
		
		Field[] fields = klass.getDeclaredFields();
		for (Field field : fields) {
			if (!field.isAnnotationPresent(Autowired.class)) {
				continue;
			}
			// 应该先对inject进行判断,若为true,表示该对象已经完成注入;
			// 这种方法可以避免循环依赖。
			field.setAccessible(true);
			Object value = getBean(field.getType());
			if (value == null) {
				throw new HasNoBeanException("类[" + klass.getName()
						+ "]的[" + field.getName()
						+ "]成员没有对应的Bean!");
			}
			try {
				field.set(object, value);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		beanDefinition.setInject(true);
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getBean(String klassName) throws RuntimeException {
		if (firstGetBean) { // 这里并没有考虑线程安全性的问题
			ParameterDependance parameterDependance = new ParameterDependance();
			//参数方法映射表里面还存在不满足参数要求的映射关系
			if (!parameterDependance.isEmpty()) {
				throw new RuntimeException(
						parameterDependance.getDependanceMessage());
			}
		}
		
		BeanDefinition bd = getBeanDefinition(klassName);
		if (bd == null) {
			return null;
		}
		
		Object result = bd.getObject();
		if (!bd.isInject()) {
			bd.setInject(true);
			injectProperties(bd);
		}
		
		return (T) result;
	}
	
	public <T> T getBean(Class<?> klass) throws RuntimeException {
		return getBean(klass.getName());
	}
	
}


           

封装参数方法映射(依赖)关系的类ParameterDependance具体内容如下。

package com.mec.spring_imitate.core;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ParameterDependance {
	private static final Map<Class<?>, List<BeanMethodDefinition>> parameterDependance;参数方法映射关系表
	static {
		parameterDependance = new ConcurrentHashMap<Class<?>, List<BeanMethodDefinition>>();
	}

	ParameterDependance() {
	}
	
	boolean isEmpty() {
		return parameterDependance.isEmpty();
	}
	
	String getDependanceMessage() {
		StringBuffer res = new StringBuffer();
		
		for (Class<?> klass : parameterDependance.keySet()) {
			List<BeanMethodDefinition> bmdList = parameterDependance.get(klass);
			for (BeanMethodDefinition bmd : bmdList) {
				res.append('\n').append(bmd.getMethod())
				.append(" 缺少对应参数: ")
				.append(klass.getName());
			}
		}
		res.append('\n');
		
		return res.toString();
	}
	boolean addDependance(BeanMethodDefinition methodDefinition) {
		Method method = methodDefinition.getMethod();
		int parameterCount = method.getParameterCount();
		//如果是无参函数,则参数与方法之间无对应关系,已满足参数要求就不往参数方法关系映射表里面加
		//如果参数要求已满足,也不往参数方法关系映射表里面加
		if (parameterCount <= 0) {
			return false;
		}
		
		Parameter[] parameters = method.getParameters();
		for (Parameter parameter : parameters) {
			Class<?> type = parameter.getType();
			//判断参数方法关系映射表里面是否有该参数类型对应的BeanMethodDefinition列表,如果没有,则新建一个
			if (!parameterDependance.containsKey(type)) {
				parameterDependance.put(type, new LinkedList<BeanMethodDefinition>());
			}
			//先取得参数类型对应的BeanMethodDefinition列表,再往列表里面加
			List<BeanMethodDefinition> bmdList = parameterDependance.get(type);
			bmdList.add(methodDefinition);
		}
		
		return true;
	}
	
	void checkOnReady(OnReadyBeanMethodDefinition onReady) {
		BeanFactory beanFactory = new BeanFactory();
		for (Class<?> klass : parameterDependance.keySet()) {
			//若需要的参数类型已准备好,则开始匹配
			if (beanFactory.getBeanDefinition(klass) != null) {
				matchDependance(klass, onReady);
			}
		}
	}
	
	void matchDependance(Class<?> klass, OnReadyBeanMethodDefinition onReady) {
		//根据参数类型取得对应的方法列表,如果为null,则说明该参数类型没有对应的方法
		List<BeanMethodDefinition> bmdList = parameterDependance.get(klass);
		if (bmdList == null) {
			return;
		}
		//循环遍历方法列表
		Iterator<BeanMethodDefinition> bmditor=bmdList.iterator();
		while (bmditor.hasNext()) {
			BeanMethodDefinition bmd = (BeanMethodDefinition) bmditor.next();
			int paraCount = bmd.decrease();paraCount成员的值减一
			if (paraCount == 0) {	//当BeanMethodDefinition的paraCount成员的值为0时,说明参数要求已得到满足,则将其加入到准备队列里面
				onReady.in(bmd);
			}
			bmditor.remove();	/*无论,BeanMethodDefinition的paraCount成员的值是否为0,
									都要从参数类型对应的方法列表里面删除*/
			if (bmdList.isEmpty()) {//当参数类型对应的方法列表为空时,则将参数与方法映射表里面的映射关系移除
				parameterDependance.remove(klass);
			}
		}
	}
}

           

封装可执行列表(准备执行列表)的类OnReadyBeanMethodDefinition具体内容如下。

package com.mec.spring_imitate.core;

import java.util.LinkedList;
import java.util.List;

public class OnReadyBeanMethodDefinition {
	private List<BeanMethodDefinition> onReadymethodDefinitionList;//可执行列表

	OnReadyBeanMethodDefinition() {
		this.onReadymethodDefinitionList = new LinkedList<BeanMethodDefinition>();
	}
	
	void in(BeanMethodDefinition bmd) {
		onReadymethodDefinitionList.add(bmd);
	}
	
	BeanMethodDefinition next() {
		return onReadymethodDefinitionList.remove(0);
	}
	
	boolean hasNext() {
		return !onReadymethodDefinitionList.isEmpty();
	}

}

           

运行时异常HasNoBeanException 具体内容如下。

`package com.mec.spring_imitate.core;

public class HasNoBeanException extends RuntimeException {

private static final long serialVersionUID = -900159240707170537L;

public HasNoBeanException() {
}

public HasNoBeanException(String message) {
	super(message);
}

public HasNoBeanException(Throwable cause) {
	super(cause);
}

public HasNoBeanException(String message, Throwable cause) {
	super(message, cause);
}

public HasNoBeanException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
	super(message, cause, enableSuppression, writableStackTrace);
}
           

}

`

正常测试代码如下图。

package com.mec.spring_imitate.test;

import com.mec.spring_imitate.core.BeanFactory;
import com.mec.spring_imitate.some_class.ClassFive;
import com.mec.spring_imitate.some_class.ClassOne;
import com.mec.spring_imitate.some_class.ClassSex;
import com.mec.spring_imitate.some_class.ClassThree;
import com.mec.spring_imitate.some_class.Complex;
import com.mec.spring_imitate.some_class.Point;
import com.mec.spring_imitate.some_class.StudentDao;

public class Demo {

	public static void main(String[] args) {
		BeanFactory beanFactory = new BeanFactory();
		beanFactory.scanBeanByPackage("com.mec.spring_imitate.some_class");
		
		Complex c1 = beanFactory.getBean(Complex.class.getName());
		System.out.println(c1);
		
		Point point = beanFactory.getBean(Point.class);
		System.out.println(point);
		
		ClassOne classOne = beanFactory.getBean(ClassOne.class);
		System.out.println(classOne);
		
		StudentDao dao = beanFactory.getBean(StudentDao.class);
		dao.getStudentById("32432");
		
//		ClassThree three = beanFactory.getBean(ClassThree.class);
//		System.out.println("three:" + three);
		
		ClassFive five=beanFactory.getBean(ClassFive.class);
		System.out.println(five);

		ClassSex sex=beanFactory.getBean(ClassSex.class);
		System.out.println(sex);
	}

}

           

正常测试结果如下图。

(0.0, 0.0), Point:[0, 0]
[0, 0]
ClassOne [complex=(0.0, 0.0), Point:[0, 0], str=null, point=[0, 0]]
database:com.mec.orm.core.Database@d716361
com.mec.spring_imitate.some_class.ClassFive@6ff3c5b5
com.mec.spring_imitate.some_class.ClassSex@3764951d


           

异常测试代码如下图。

package com.mec.spring_imitate.test;

import com.mec.spring_imitate.core.BeanFactory;
import com.mec.spring_imitate.some_class.ClassFive;
import com.mec.spring_imitate.some_class.ClassOne;
import com.mec.spring_imitate.some_class.ClassSex;
import com.mec.spring_imitate.some_class.ClassThree;
import com.mec.spring_imitate.some_class.Complex;
import com.mec.spring_imitate.some_class.Point;
import com.mec.spring_imitate.some_class.StudentDao;

public class Demo {

	public static void main(String[] args) {
		BeanFactory beanFactory = new BeanFactory();
		beanFactory.scanBeanByPackage("com.mec.spring_imitate.some_class");
		
		Complex c1 = beanFactory.getBean(Complex.class.getName());
		System.out.println(c1);
		
		Point point = beanFactory.getBean(Point.class);
		System.out.println(point);
		
		ClassOne classOne = beanFactory.getBean(ClassOne.class);
		System.out.println(classOne);
		
		StudentDao dao = beanFactory.getBean(StudentDao.class);
		dao.getStudentById("32432");
		
		ClassThree three = beanFactory.getBean(ClassThree.class);
		System.out.println("three:" + three);
		
		ClassFive five=beanFactory.getBean(ClassFive.class);
		System.out.println(five);

		ClassSex sex=beanFactory.getBean(ClassSex.class);
		System.out.println(sex);
	}

}

           

异常测试结果如图。

Exception in thread "main" java.lang.RuntimeException: 
public com.mec.spring_imitate.some_class.ClassThree com.mec.spring_imitate.some_class.Configuration.getClassThree(com.mec.spring_imitate.some_class.ClassFour) 缺少对应参数: com.mec.spring_imitate.some_class.ClassFour

	at com.mec.spring_imitate.core.BeanFactory.getBean(BeanFactory.java:181)
	at com.mec.spring_imitate.test.Demo.main(Demo.java:18)

           

        由于Configuration里面的public ClassThree   getClassThree(ClassFour four)方法需要的参数ClassFour four既没有加Component注解,也没有获得它的带有Bean注解的方法,因此在BeanFactory里面的beanPool里面没有ClassFour对应的BeanDefinition,所以在其它参数方法映射关系被处理完后,参数方法映射关系表里还剩下ClassFour对应的映射关系尚未满足,所以报出以上错误,但这恰证明我们的方法是正确的。

测试用例类

Configuration 类

package com.mec.spring_imitate.some_class;

import com.mec.orm.core.Database;
import com.mec.spring_imitate.annotation.Bean;
import com.mec.spring_imitate.annotation.Component;

@Component
public class Configuration {

	public Configuration() {
	}

	@Bean
	public Database getDatabase() {
		Database database = new Database();
		
		return database;
	}
	
	@Bean
	public ClassFive getClassFive(Complex complex) {
		return new ClassFive(complex);
	}
	
	@Bean
	public ClassThree getClassThree(ClassFour four) {
		return new ClassThree(four);
	}
	
	@Bean
	public ClassSex getClassSex(ClassFive five,ClassSeven seven) {
		return new ClassSex(five, seven);
	}
	
}

           

ClassThree类

package com.mec.spring_imitate.some_class;

public class ClassThree {
	private ClassFour four;

	public ClassThree(ClassFour four) {
		this.four = four;
	}

	public ClassFour getFour() {
		return four;
	}

	public void setFour(ClassFour four) {
		this.four = four;
	}

	@Override
	public String toString() {
		return "ClassThree [four=" + four + "]";
	}

}

           

ClassFour类

package com.mec.spring_imitate.some_class;

public class ClassFour {
	private ClassThree three;
	
	public ClassFour(ClassThree three) {
		this.three = three;
	}

	public ClassThree getThree() {
		return three;
	}

	public void setThree(ClassThree three) {
		this.three = three;
	}

	@Override
	public String toString() {
		return "ClassFour [three=" + three + "]";
	}

}

           

ClassFive类

package com.mec.spring_imitate.some_class;

public class ClassFive {
	
	private Complex complex;
	
	public ClassFive() {
		
	}
	
	public ClassFive(Complex complex) {
		this.complex=complex;
	}
}

           

ClassSex类

package com.mec.spring_imitate.some_class;

public class ClassSex {
	private ClassFive five;
	private ClassSeven seven;
	
	public ClassSex() {
		
	}
	
	public ClassSex(ClassFive five,ClassSeven seven) {
		this.five=five;
		this.seven=seven;
	}
	
}

           

ClassSeven类

package com.mec.spring_imitate.some_class;

import com.mec.spring_imitate.annotation.Component;

@Component
public class ClassSeven {
	
	public ClassSeven() {
		
	}
}

           

总结

        无法增加注解的类,通过给方法增加注解Bean的方式也能变为BeanFactory里面的BeanDefinition,然后再通过注入的方式来处理循环依赖,如果采用XML文件配置的方式,无需增加注解,而通过Bean标签,指明哪个类以及成员需要注入即可。

下载地址:https://github.com/dx99606707/depository/blob/master/Spring模拟实现依赖注入之方法注入.rar

上一篇:Spring 依赖注入——模拟实现(一)(对象注入)

下一篇:Spring 应用示例