解决 Java 反射时对象之间的循环依赖问题

Spring如何解决bean之间的循环依赖的问题 问题, 做简要代码实现解决对象之间的循环依赖问题。配合 BGDI 组件实现简单 Spring IOC容器及其依赖注入特性。结合 spring的scope为prototype的bean的正确使用方法 实现 bean 的多实例注入

  • Spring是通过递归的方式获取目标bean及其所依赖的bean的;
  • Spring实例化一个bean的时候,是分两步进行的,首先实例化目标bean,然后为其注入属性。

结合这两点,也就是说,Spring在实例化一个bean的时候,是首先递归的实例化其所依赖的所有bean,直到某个bean没有依赖其他bean,此时就会将该实例返回,然后反递归的将获取到的bean设置为各个上层bean的属性的。

 

public class ServiceA {
    private ServiceB serviceB;

    public String query() {
        System.out.println("ServiceA query...");
        return "A";
    }
}
public class ServiceB {
    private ServiceA serviceA;

    public String query() {
        System.out.println("ServiceB query...");
        return "B";
    }
}

 

	// 对象实例化结果存储容器
	private static final HashMap<String, Object> CLASSES_MAP = Maps.newHashMap();
	// 通过注解获取需要注入的对象信息
    private static final List<Class<?>> INIT_CLASSES = Lists.newArrayList(ServiceA.class, ServiceB.class);
    
    public static void main(String[] args) throws Exception {
        System.out.println("加载bean...");
        for (Class<?> clz : INIT_CLASSES) {
            injection(clz);
        }

        System.out.println("执行方法...");
        for (Class<?> clz : INIT_CLASSES) {
            String clzName = clz.getName();
            if (!CLASSES_MAP.containsKey(clzName)) {
                System.out.println(String.format("容器中不包含clzName=[%s]", clzName));
                continue;
            }
            Object object = CLASSES_MAP.get(clzName);
            Method[] declaredMethods = clz.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                declaredMethod.invoke(object);
            }
            System.out.println();
        }
    }


    private static void injection(Class<?> clz) throws Exception {
        String clzName = clz.getName();
        if (!CLASSES_MAP.containsKey(clzName)) {
            // 实例化对象
            Object instance = clz.newInstance();
            CLASSES_MAP.put(clzName, instance);

            Field[] declaredFields = clz.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                Class<?> fldClz = declaredField.getType();
                String fldTypeClzName = fldClz.getName();
                // 如果属性未被实例化, 先实例化属性并注入到容器
                if (!CLASSES_MAP.containsKey(fldTypeClzName)) {
                    // 递归实例化属性并注入
                    injection(fldClz);
                }

                declaredField.setAccessible(true);
                // 注入属性, 设置对象属性值
                declaredField.set(instance, CLASSES_MAP.get(fldTypeClzName));
            }
        }

    }

 

Spring如何解决循环依赖的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值