极轻量级IOC简单实现

极轻量级IOC简单实现

一、IOC概念引入

提起Spring,必然会提到IOC(控制反转)和AOP(面向切面编程)。今天我们简单的介绍一下IOC,并且通过代码,更加清晰的认识IOC。

控制反转(Inversion of Control,缩写为IoC)。有人就问了,谁控制谁?如何翻转?

在我们日常的程序设计当中,一个类中有多个成员,我们需要将其一个一个的new出来。若其中一个类是接口,又存在多个实现类,当需求发生变化时,我们不得不去更改源代码,尤其当代码量上去之后,牵一线动全发,这种代价使我们不愿意接受的。如果这种更改交给用户来进行配置,而不由我们(编写程序的人)去解决,那么这个问题就得到了很好的解决。
用户所需要的这些成员,都被放在了一个容器中,当用户需要时,从容器中取得该成员。举一个例子:这个容器就相当于一个婚介所,你请求你想要找的对象,这个婚介所就会按照你的要求来帮你找到这个对象。如果没有找到,就抛出异常。
对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被容器控制,所以这叫控制反转。

更详细内容查看IOC概念的简单理解.

二、IOC功能分析

  1. 可以自动的注入指定类的中的复杂类成员对象,通过set方法注入。

  2. 八大基本类型和String类型可以通过注解的value直接赋值进行注入,也可以通过bean工厂注入。若注入的类为接口,而接口实现类存在多个,可以通过value直接进行类的指定,若不指定,则随机注入

  3. 这些注入的bean需要被存储起来,即需要一个map<String, BeanDefinition> beanFactory

  4. 循环依赖问题,A需要B,B需要A,这种问题如何解决?

​ 答曰:创建beanDefinition,存在inject成员,判断是否注入。当注入成员时,先将inject设为true,再开始真正注入

  1. 如何辨别一个类需要被注入?

​ 答曰:添加==@Component注解,并且给需要注入的成员加@Autowired==注解

  1. 注入的时机,是直接注入还是等到用户获取这个bean的时候才进行注入

​ 答曰:先不着急注入bean,而是等到用户需要时,在进行bean注入,懒汉模式

  1. 对于只有.class文件的类,无法增加==@Component注解,只能通过某个方法的返回值来获得,这时候,需要一个@bean==注解来处理

三、关于bean注解的讨论

@bean注解只作用于方法
方法的返回值是一个bean
允许方法的参数是其他bean

这里就引出来一个很严重的问题,一个带参的方法,必然依赖其他的参数才能执行,但是当进行包扫描时,这个依赖不一定会满足,可能等到下一次扫描后,依赖才满足。这里就需要当每生成一个bean后,对这些依赖关系进行动态调整。

其中,当每发现一个带参的method时,需要用一个BeanMethodDefinition来进行保存,并存储到一个集合中。存储当然是使用Map进行存储,Map<BeanMethodDefinition,HashSet>。

​ 使用HashSet的原因是,一个BeanMethodDefinition可能会有多个未满足的参数,而HashSet是基于散列表实现的,元素没有顺序;add、remove、contains方法的时间复杂度为O(1)。

其中所有依赖满足的方法放入一个List中,List,方便后面生成所需要的bean。

我们也得再考虑一下,如何根据一个bean快速查找到一堆依赖他的BeanMethodDefinition,则需要构建另一个Map。

Map<Class<?>, List>.

四、关于接口及其实现类的讨论

当需要的类为接口时,遍历beanFactory。通过isAssignableFrom()方法进行判断。若为真,则找到

klass.isAssignableFrom(beanClass)

五、构建Bean过程图

在这里插入图片描述

六、具体代码

1.工具类

PackageScanner.java
public abstract class PackageScanner {
	
	public PackageScanner() {
	}
	
	public abstract void dealClass(Class<?> klass) throws Exception;
	
	private void scanJar(URL url) throws Exception {
		JarURLConnection connection = (JarURLConnection) url.openConnection();
		JarFile jarFile = connection.getJarFile();
		Enumeration<JarEntry> entries = jarFile.entries();
		while (entries.hasMoreElements()) {
			JarEntry entry = entries.nextElement();
			if (entry.isDirectory() || !entry.getName().endsWith(".class")) {
				continue;
			}
			String className = entry.getName().replace(".class", "");
			className = className.replace('/', '.');
			Class<?> klass = Class.forName(className);
			dealClass(klass);
		}
	}
	
	private void scanFile(File dir, String packageName) throws Exception {
		File[] files = dir.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				scanFile(file, packageName + "." + file.getName());
			} else if (file.isFile() && file.getName().endsWith(".class")) {
				String className = packageName + "." + file.getName().replace(".class", "");
				Class<?> klass = Class.forName(className);
				dealClass(klass);
			}
		}
	}
	
	public void packageScan(String packageName) throws Exception {
		String path = packageName.replace('.', '/');
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		Enumeration<URL> urls = classLoader.getResources(path);
		while (urls.hasMoreElements()) {
			URL url = urls.nextElement();
			if (url.getProtocol().equals("file")) {
				File file = new File(url.toURI());
				scanFile(file, packageName);
			} else if (url.getProtocol().equals("jar")) {
				scanJar(url);
			}
		}
	}
	
}
TypeParser.java
public class TypeParser {
	private static final Map<String, Class<?>> classPool = new HashMap<String, Class<?>>();
	private static final Map<String, IValueParser> valuePool = new HashMap<String, IValueParser>();
	
	static {
		classPool.put("byte", byte.class);
		classPool.put("char", char.class);
		classPool.put("boolean", boolean.class);
		classPool.put("short", short.class);
		classPool.put("int", int.class);
		classPool.put("long", long.class);
		classPool.put("float", float.class);
		classPool.put("double", double.class);
		classPool.put("string", String.class);
		
		valuePool.put("byte", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return Byte.valueOf(str);
			}
		});
		valuePool.put("char", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return str.charAt(0);
			}
		});
		valuePool.put("boolean", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return Boolean.valueOf(str);
			}
		});
		valuePool.put("short", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return Short.valueOf(str);
			}
		});
		valuePool.put("int", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return Integer.valueOf(str);
			}
		});
		valuePool.put("long", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return Long.valueOf(str);
			}
		});
		valuePool.put("float", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return Float.valueOf(str);
			}
		});
		valuePool.put("double", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return Double.valueOf(str);
			}
		});
		valuePool.put("string", new IValueParser() {
			@Override
			public Object toValue(String str) {
				return str;
			}
		});
	}

	public TypeParser() {
	}

	public static Class<?> toType(String strType) {
		Class<?> result = classPool.get(strType);
		if (result == null) {
			try {
				result = Class.forName(strType);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}
	
	public static Object getValue(String type, String strValue) {
		IValueParser valueParser = valuePool.get(type);
		if (valueParser != null) {
			return valueParser.toValue(strValue);
		}
		
		return null;
	}
	
}

2.基础类

Component.java
/**
 * 包扫描的入口,表示这个类存在需要被注入的成员或者生成bean的方法
 * @Author :漠殇
 * @Data :Create in 17:22 2021/7/18
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}
Autowired.java
/**
 * 表示该成员需要被注入
 * @Author :漠殇
 * @Data :Create in 17:24 2021/7/18
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
    String value() default "";
}
Bean.java
/**
 * 表示这个方法会生成一个Bean
 * @Author :漠殇
 * @Data :Create in 17:25 2021/7/18
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Bean {
}
BeanDefinition.java
/**
 * @Author :漠殇
 * @Data :Create in 17:29 2021/7/18
 */
public class BeanDefinition {
    private Class<?> klass;
    private Object object;
    private boolean inject;

    public BeanDefinition() {
    }

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

    public BeanDefinition setKlass(Class<?> klass) {
        this.klass = klass;
        return this;
    }

    public Object getObject() {
        return object;
    }

    public BeanDefinition setObject(Object object) {
        this.object = object;
        return this;
    }

    public boolean isInject() {
        return inject;
    }

    public BeanDefinition setInject(boolean inject) {
        this.inject = inject;
        return this;
    }

    @Override
    public String toString() {
        return "BeanDefinition{" +
                "klass=" + klass +
                ", object=" + object +
                ", inject=" + inject +
                '}';
    }
}
BeanMethodDefinition.java
/**
 * 存放方法,方法执行的对象,和方法还缺少依赖参数的个数
 * 依赖参数个数为0,说明可以直接执行
 * @Author :漠殇
 * @Data :Create in 17:30 2021/7/18
 */
public class BeanMethodDefinition {
    private Class<?> klass;
    private Object object;
    private Method method;
    private int relyCount;

    public BeanMethodDefinition() {
    }

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

    public BeanMethodDefinition setKlass(Class<?> klass) {
        this.klass = klass;
        return this;
    }

    public Object getObject() {
        return object;
    }

    public BeanMethodDefinition setObject(Object object) {
        this.object = object;
        return this;
    }

    public Method getMethod() {
        return method;
    }

    public BeanMethodDefinition setMethod(Method method) {
        this.method = method;
        return this;
    }

    public int getRelyCount() {
        return relyCount;
    }

    public BeanMethodDefinition setRelyCount(int relyCount) {
        this.relyCount = relyCount;
        return this;
    }

    @Override
    public String toString() {
        return "BeanMethodDefinition{" +
                "klass=" + klass +
                ", object=" + object +
                ", method=" + method +
                ", relyCount=" + relyCount +
                '}';
    }
}

3.核心类

BeanFactory.java
/**
 * 所有的bean存放的位置
 * 完成对bean的扫描,获取和判断bean是否存在等功能
 * @Author :漠殇
 * @Data :Create in 17:33 2021/7/18
 */
public class BeanFactory {
    private static final Map<String, BeanDefinition> beanPool;

    static {
        beanPool = new HashMap<>();
    }

    public BeanFactory() {
    }

    /**
     * 通过包路径,完成对bean工厂的初始化.
     * 添加了Component注解的一定是一个bean,先将其加入beanFactory,并且调整依赖关系
     * 然后对这个bean的方法进行扫描,若发现@bean注解,处理有参和无参方法
     * 扫描完成后,将所有的依赖满足的method执行之,将结果返回值的Definition放回到bean工厂
     * @param packagePath
     */
    public static void scanPackage(String packagePath) {
        try {
            new PackageScanner() {
                @Override
                public void dealClass(Class<?> klass) throws Exception {
                    if (klass.isInterface()
                            ||klass.isAnnotation()
                            ||klass.isArray()
                            ||klass.isEnum()
                            ||klass.isPrimitive()
                            ||!klass.isAnnotationPresent(Component.class)) {
                        return;
                    }

                    Object object = klass.newInstance();
                    BeanDefinition bd = new BeanDefinition();
                    bd.setKlass(klass).setObject(object).setInject(false);

                    beanPool.put(klass.getName(), bd);
                    MethodDependOnClass.judgeMethodDependOnClass(klass); //判断依赖关系

                    Method[] methods = klass.getDeclaredMethods();
                    for (Method method: methods) {
                        if (!method.isAnnotationPresent(Bean.class)) {
                            continue;
                        }
                        doMethodArgJudge(method, bd); //处理无参和有参方法
                    }
                }
            }.packageScan(packagePath);

            doBeanMethod();//执行所有的完成依赖关系的BeanMethodDefinition
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取bean
     * @param klass
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<?> klass) {
        return getBean(klass.getName());
    }

    /**
     * 获取bean
     * 先才beanFactory中寻找,如果未找到,寻找这个类的实现类,
     * 再没有的话,就是这个bean不存在,或者生成这个bean的方法有参数未满足
     * @param klassName
     * @param <T>
     * @return
     */
    public static <T> T getBean(String klassName){
        BeanDefinition beanDefinition = beanPool.get(klassName);
        if (beanDefinition == null) {
            //处理接口的实现类
            beanDefinition = getImplementBean(klassName);
            //处理不满足依赖和不存在的问题
            if (beanDefinition == null) {
                BeanMethodDefinition beanMethodDefinition = BeanMethodDepends.getBeanMethodDefinitionByClassName(klassName);
                if (beanMethodDefinition == null) {
                    return null;
                }
                String str = BeanMethodDepends.getDependRelationship(beanMethodDefinition);
                try {
                    throw new BeanMissingDependentException(str);
                } catch (BeanMissingDependentException e) {
                    e.printStackTrace();
                }
            }
        }

        if (beanDefinition == null) {
            return null;
        }

        Object bean = beanDefinition.getObject();
        try {
            doInject(beanDefinition);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return (T) bean;
    }

    /**
     * 完成bean的注入
     * 通过扫描@Autowired注解
     *      判断是否为八大基本类型和String,如果是:如果value.length>0,进行值转换,负责,从beanFactory中获取
     *      如果是其他类型,存在成员是接口类型:
     *          如果value.length>0,根据value的值从beanFactory中获取(自定义获取)
     *          否则,直接从beanFactory中获取(随机获取)
     * 这里支持参数可以为null,即bean的某个成员的值可以为null
     * @param bean
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private static void doInject(BeanDefinition bean) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        if (bean.isInject()) {
            return;
        }
        bean.setInject(true);

        Class<?> klass = bean.getKlass();
        Object object = bean.getObject();
        Field[] fields = klass.getDeclaredFields();

        for (Field field : fields) {
            if (!field.isAnnotationPresent(Autowired.class)) {
                continue;
            }
            Autowired autowired = field.getAnnotation(Autowired.class);
            String value = autowired.value();

            Object property = null;
            Class<?> filedType = field.getType();
            String typeName = filedType.getName();

            if (filedType.isPrimitive() || filedType.isAssignableFrom(String.class)) {
                if (value.length() <= 0 ) {
                    property = getBean(typeName);
                } else {
                    property = TypeParser.getValue(typeName, value);
                }
            } else {
                if (value.length() <= 0) {
                    property = getBean(typeName);
                } else {
                    property = getBean(value);
                }
            }

            String filedName = field.getName();
            String setStr = "set" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);

            Method method = klass.getDeclaredMethod(setStr, filedType);
            method.invoke(object, property);
        }
    }

    /**
     * 这里的方法必须含有返回值
     * 处理无参方法和有参方法:
     * 无参方法直接执行,生成bean
     * 有参方法则进行依赖判断 BeanMethodDepends.addBeanMethod(method, object);
     * @param method
     * @param beanDefinition
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private static void doMethodArgJudge(Method method, BeanDefinition beanDefinition) throws InvocationTargetException, IllegalAccessException {
        Object object = beanDefinition.getObject();

        if (method.getParameterCount() <= 0) {
            Object res = method.invoke(object, new Object[] {});
            Class<?> klass = res.getClass();
            BeanDefinition bd = new BeanDefinition().setKlass(klass)
                    .setObject(res).setInject(false);
            beanPool.put(klass.getName(), bd);
            MethodDependOnClass.judgeMethodDependOnClass(klass); //判断依赖关系
            return;
        } else {
            BeanMethodDepends.addBeanMethod(method, object);
        }
    }

    /**
     * 将所有完成依赖的方法执行之,生成bean,放入beanFactory中
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private static void doBeanMethod() throws InvocationTargetException, IllegalAccessException {
        while (BeanMethodDepends.hasNext()) {
            BeanMethodDefinition beanMethodDefinition = BeanMethodDepends.next();
            Object object = beanMethodDefinition.getObject();
            Method method = beanMethodDefinition.getMethod();

            Parameter[] parameters = method.getParameters();
            Object[] objects = new Object[method.getParameterCount()];

            for (int i = 0; i < parameters.length; i++) {
                Class<?> klass = parameters[i].getType();
                objects[i] = getBean(klass.getName());

            }

            Object bean = method.invoke(object, objects);
            Class<?> beanClass = bean.getClass();

            BeanDefinition beanDefinition = new BeanDefinition();
            beanDefinition.setKlass(beanClass).setObject(bean).setInject(false);

            beanPool.put(beanClass.getName(), beanDefinition);
            MethodDependOnClass.judgeMethodDependOnClass(beanClass); //判断依赖关系
        }
    }

    /**
     * 获取接口的实现类
     * @param klassName
     * @return
     */
    private static BeanDefinition getImplementBean(String klassName){
        try {
            Class<?> klass = Class.forName(klassName);
            if (klass.isInterface()) {
                for (BeanDefinition beanDefinition : beanPool.values()) {
                    Class<?> beanClass = beanDefinition.getKlass();
                    if (klass.isAssignableFrom(beanClass)) {
                        return beanDefinition;
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            return null;
        }
        return null;
    }


    /**
     * 判断是否存在这个bean
     * @param klassName
     * @return
     */
    public static boolean hasBean(String klassName) {
        if (beanPool.containsKey(klassName)) {
            return true;
        }

        if (getImplementBean(klassName) != null) {
            return true;
        }

        return false;
    }

    /**
     * 判断是否存在这个Bean
     * @param klass
     * @return
     */
    public boolean hasBean(Class<?> klass) {
        String klassName = klass.getName();
        return hasBean(klassName);
    }
}

BeanMethodDepends.java
/**
 * 未满足依赖的methodDependPool和已经完成依赖的readyList
 * 每当存入新的bean,这两个就会动态调整
 * @Author :漠殇
 * @Data :Create in 18:32 2021/7/18
 */
public class BeanMethodDepends {
    private static final Map<BeanMethodDefinition, HashSet<Class<?>>> methodDependPool;
    private static final List<BeanMethodDefinition> readyList;

    static {
        methodDependPool = new HashMap<>();
        readyList = new ArrayList<>();
    }

    BeanMethodDepends() {
    }

    /**
     * 当一个bean已生成,去调整之前需要依赖这个bean但之前没有满足的beanMethodDefinition
     * 且调整后,如果beanMethodDefinition的未依赖参数个数为0,
     * 则将其加入到readyList,并从methodDependPool中移除
     * @param klass
     * @param beanMethodDefinition
     */
    static void adjustDependRelationship(Class<?> klass, BeanMethodDefinition beanMethodDefinition) {
        HashSet<Class<?>> hashSet = methodDependPool.get(beanMethodDefinition);
        hashSet.remove(klass);
        beanMethodDefinition.setRelyCount(beanMethodDefinition.getRelyCount() - 1);
        if (beanMethodDefinition.getRelyCount() <= 0) {
            methodDependPool.remove(beanMethodDefinition);
            readyList.add(beanMethodDefinition);
        }
    }

    /**
     * 判断readyList中是否还有元素
     * @return
     */
    static boolean hasNext() {
        return !readyList.isEmpty();
    }

    /**
     * 得到当前readyList中的第一个元素
     * @return
     */
    static BeanMethodDefinition next() {
        if(!hasNext()) {
            return null;
        }
        return readyList.remove(0);
    }

    /**
     * 根据method和object构建BeanMethodDefinition
     * 判断参数是否完成依赖,选择放入两个池子中的一个
     * @param method
     * @param object
     */
    static void addBeanMethod(Method method, Object object) {
        BeanMethodDefinition bmd = new BeanMethodDefinition();
        bmd.setMethod(method).setObject(object).setKlass(method.getReturnType());

        Parameter[] parameters = method.getParameters();
        HashSet<Class<?>> hashSet = new HashSet<>();
        for (Parameter parameter : parameters) {
            Class<?> paraType = parameter.getType();
            if (BeanFactory.hasBean(paraType.getName())) {
                continue;
            }
            hashSet.add(paraType);
            // 添加类和BeanMethodDefinition的依赖
            MethodDependOnClass.addMethodDependOnClass(paraType, bmd);
        }
        int relyCount = hashSet.size();
        bmd.setRelyCount(relyCount);

        if (relyCount <= 0) {
            readyList.add(bmd);
        } else {
            methodDependPool.put(bmd, hashSet);
        }
    }

    /**
     * 通过类名称,从methodDependPool中获取他对应的BeanMethodDefinition
     * @param className
     * @return
     */
    static BeanMethodDefinition getBeanMethodDefinitionByClassName(String className) {
        if (methodDependPool.isEmpty()) {
            return null;
        }

        for (BeanMethodDefinition beanMethodDefinition : methodDependPool.keySet()) {
            Class<?> klass = beanMethodDefinition.getKlass();
            if (klass.getName().equals(className)) {
                return beanMethodDefinition;
            }
        }

        return null;
    }

    /**
     * 构建beanMethodDefinition所未完成依赖参数的字符串
     * @param beanMethodDefinition
     * @return
     */
    static String getDependRelationship(BeanMethodDefinition beanMethodDefinition) {
        HashSet<Class<?>> hashSet = methodDependPool.get(beanMethodDefinition);
        StringBuffer dependRelationship = new StringBuffer(beanMethodDefinition.getMethod().getName()
                                             + "依赖于 --> ");
        boolean isFirst = true;

        for (Iterator<Class<?>> it = hashSet.iterator(); it.hasNext(); ) {
            Class<?> iterator = it.next();
            if (isFirst) {
                dependRelationship.append(iterator.getName()).append(" ");
                isFirst = false;
            } else {
                dependRelationship.append(", ").append(iterator.getName()).append(" ");
            }
        }

        return dependRelationship.toString();
    }

}

MethodDependOnClass.java
/**
 * 一个类可能存在多个BeanMethodDefinition去依赖他
 * 当一个类进入到beanFactory中,可以将整个所依赖于他的BeanMethodDefinition的依赖关系全部进行调整
 * @Author :漠殇
 * @Data :Create in 15:09 2021/7/19
 */
public class MethodDependOnClass {
    private static final Map<Class<?>, List<BeanMethodDefinition>> methodDependOnClassPool;

    static {
        methodDependOnClassPool = new HashMap<>();
    }

    MethodDependOnClass() {
    }

    /**
     * 根据beanClass得到依赖于他的List<BeanMethodDefinition>
     * @param beanClass
     * @return
     */
    static List<BeanMethodDefinition> getDependListByClass(Class<?> beanClass) {
        return methodDependOnClassPool.get(beanClass);
    }

    /**
     * 添加类与beanMethodDefinition的依赖列表
     * @param beanClass
     * @param beanMethodDefinition
     */
    static void addMethodDependOnClass(Class<?> beanClass, BeanMethodDefinition beanMethodDefinition) {
       if (!methodDependOnClassPool.containsKey(beanClass)) {
           methodDependOnClassPool.put(beanClass, new ArrayList<>());
       }

       List<BeanMethodDefinition> beanMethodDefinitionList = methodDependOnClassPool.get(beanClass);
       beanMethodDefinitionList.add(beanMethodDefinition);
    }

    /**
     * 根据新生成的beanClass调整依赖关系
     * @param beanClass
     */
    static void judgeMethodDependOnClass(Class<?> beanClass) {
        if (!methodDependOnClassPool.containsKey(beanClass)) {
            return;
        }

        List<BeanMethodDefinition> beanMethodDefinitionList = methodDependOnClassPool.get(beanClass);
        methodDependOnClassPool.remove(beanClass);
        while (!beanMethodDefinitionList.isEmpty()) {
            BeanMethodDefinition beanMethodDefinition = beanMethodDefinitionList.remove(0);
            BeanMethodDepends.adjustDependRelationship(beanClass, beanMethodDefinition);
        }
    }

}

BeanMissingDependentException.java
/**
 * 参数缺失错误
 * @Author :漠殇
 * @Data :Create in 18:47 2021/7/19
 */
public class BeanMissingDependentException extends Exception{
    public BeanMissingDependentException() {
        super();
    }

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

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

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

    protected BeanMissingDependentException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

七,结语

笔者只进行了循环依赖问题、赋初值、Bean注解的测试、接口类对象的测试。测试结果很令人振奋。

大家如果进行测试,发现问题,请不吝赐教。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值