开发者社区> 问答> 正文

读过Spring源码的同志请留步,问个问题。

AbstractBeanFactory这个类的doGetBean是进行bean依赖的注入并返回填充好的bean实例,请问一下

final RootBeanDefinition mbd =getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
 if (dependsOn != null) {
    for (int i = 0; i < dependsOn.length; i++) {
    String dependsOnBean = dependsOn[i];
        //这里有个回调函数
    getBean(dependsOnBean); 
        //注册依赖注入bean
        registerDependentBean(dependsOnBean, beanName);
    }
}

这个是依赖bean的注入部分代码,回调函数一直看不懂为什么这样做,而且最近想设计一个IOC但是由于出现一个问题让我很费神,问题描述如下:

UserService 中有accountService(AccountService)的引用,而AccountService中有userService(UserService)的引用,属于循环引用,这个在该类中也说明不允许存在循环依赖,但是其实我们用Spring时可以这样注入,如果不看这个细节,那么上面的A依赖B,B依赖A的情况如何去考虑和实现呢?求思路、方法!!!!

展开
收起
a123456678 2016-03-16 13:39:20 2153 0
1 条回答
写回答
取消 提交回答
  • class A{
        B b;
    }
     
    class B{
         
        A a;
    }
     
    class FactoryBean{
         
        Map<String, Object> beanMap = new HashMap<String, Object>();
        public Object getBean(){
            A a = new A();
            B b = new B();
            try {
     
            Field f1 = b.getClass().getDeclaredField("a");
            f1.setAccessible(true);
            f1.set(b, a);
             
            Field f = a.getClass().getDeclaredField("b");
            f.setAccessible(true);
            f.set(a,b);
                 
            f1.set(b, a);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return a;
        }
    }
         
    public class Test1 {
        public static void main(String[] args) {
            A a = (A)new FactoryBean().getBean();
            System.out.println("-------");
            System.out.println(a.b);
            System.out.println(a.b.a+"="+a);
        }
    }

    在反射设置属性时这里是模仿spring的构建bean的情况,A经过初始化后spring检查下面是否有引用如果有引用则进行预先初始化A中的引用依赖,就是B b = new B();但是B需要a的实例,所以直接将A a=new A();中的a设置进去,当然这里的a经过实例化后成员变量a.b是null,然后再设置a中应用的b,此时B中的a是不完整的,然而最后一句f1.set(b, a);再补充设置b中的a,就完整了。运行结果如下:
    System.out.println("-------");

    System.out.println(a.b+"="+a.b.a.b);

    System.out.println(a.b.a+"="+a);

    com.ins.base.test.B@ca0b6=com.ins.base.test.B@ca0b6

    com.ins.base.test.A@10b30a7=com.ins.base.test.A@10b30a7

    说明引用是完整的,不知道这样理解和分析是否正确,请确认下咯。

    2019-07-17 19:03:50
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载