依赖注入和循环依赖注入

依赖注入和循环依赖注入

1.java bean注入的两种方式
1.1 Resource注解方式
@Resource
private NestedComponent nestedComponent2;

1.2 构造器注入的方式来
private NestedComponent nestedComponent1;

// 构造器注入的方式来 @Resource java: 注释类型不适用于该类型的声明

    @Autowired
    public OuterComponent(NestedComponent nestedComponent1) {
        this.nestedComponent1 = nestedComponent1;
    }


1.3 //自己注入自己 报错了 Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
NestedComponent ss = (NestedComponent)(AopContext.currentProxy());

1.4 以上两种方式需要在容器中运行才可以执行。而不能运行main方法。

package com.mytest.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 *
 在主类中定义内部类
 剥离出去,形成独立的类,否则就会报下面的错误。
 The dependencies of some of the beans in the application context form a cycle:

 ┌─────┐
 |  outerComponent defined in file [D:\git\version3\mytest\mytestDock-service\build\classes\java\main\com\mytest\service\OuterComponent.class]
 ↑     ↓
 |  com.mytest.service.OuterComponent$NestedComponent
 └─────┘
 */

独立的类
package com.mytest.service;

import org.springframework.stereotype.Component;

@Component
public class NestedComponent {

}
 
 
@Component
//@Service
public class OuterComponent {
    private NestedComponent nestedComponent1;

//        构造器注入的方式来  @Resource   java: 注释类型不适用于该类型的声明
    @Autowired
    public OuterComponent(NestedComponent nestedComponent1) {
        this.nestedComponent1 = nestedComponent1;
    }

    public OuterComponent() {
    }

    //使用字段注入
//    @Autowired
//    @Resource
//    private NestedComponent nestedComponent2;

    // 使用nestedComponent的方法...

    //剥离出去,形成独立的类,否则就会报上面的错误。
//    @Component
//    public class NestedComponent {
//        // NestedComponent的实现...
//    }

    public void print1(){
        System.out.println("nestedComponent1=" + nestedComponent1.toString());
    }

//    public void print2(){
//        System.out.println("nestedComponent2=" + nestedComponent2.toString());
//    }


//    public static void main(String[] args) {
//        OuterComponent outer = new OuterComponent();
////        outer.print1();
//        outer.print2();
//    }
}

 

1.相互嵌套注入,spring中可以,不会报错

package com.mytest.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 在Spring等依赖注入框架的帮助下,循环依赖可以被正确解决,但在没有使用这些框架的情况下,需要手动管理依赖关系,避免循环依赖的发生。
 * 使用setXXX方式注入对象
 */
@Component
public class ClassA {
    /**
     * 使用依赖查找或注入框架:比如Spring框架,它可以管理对象的生命周期,并解决循环依赖问题。
     */
    @Autowired
    private ClassB b;

    public ClassA() {}

}


package com.mytest.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ClassB {
    @Autowired
    private ClassA a;

    public ClassB() {}

}

 

2.手动管理依赖关系
1.构造函数的方式会报错

package com.example.core.mydemo.bean;

public class ClassB {
    public ClassA a;

    public ClassB() {
        super();
        a = new ClassA();
    }
}


package com.example.core.mydemo.bean;

public class ClassA {
    private ClassB b;

    /**
     * 构造函数注入:使用构造函数来传递依赖,而不是使用字段注入或方法注入。 会相互依赖的注入初始化对象
     */
    public ClassA() {
        super();
        b = new ClassB();
    }

    public static void main(String[] args) {
        ClassA a = new ClassA();
        System.out.println("b=" + a.b.toString());

        ClassB b = new ClassB();
        System.out.println("a=" + b.a.toString());
    }
}

output循环打印报错信息:
Exception in thread "main" java.lang.StackOverflowError
    at com.example.core.mydemo.bean.ClassB.<init>(ClassB.java:8)
    at com.example.core.mydemo.bean.ClassA.<init>(ClassA.java:11)
    at com.example.core.mydemo.bean.ClassB.<init>(ClassB.java:8)
    at com.example.core.mydemo.bean.ClassA.<init>(ClassA.java:11)

2.使用setXXX方法可以初始化对象

package com.example.core.mydemo.bean;

public class ClassB {
    public ClassA a;

    public ClassB() {}
    /**
     * 使用setter方法注入:先创建对象,然后使用setter方法设置依赖。
     * @param a
     */
    public void setA(ClassA a) {
        this.a = a;
    }
}


package com.example.core.mydemo.bean;

public class ClassA {
    private ClassB b;

    public ClassA() {}

    /**
     * 使用setter方法注入:先创建对象,然后使用setter方法设置依赖。  这种方式可以控制
//     * @param b
     */
    public void setB(ClassB b) {
        this.b = b;
    }

    public static void main(String[] args) {
        ClassA a = new ClassA();
        ClassB b = new ClassB();

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

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

output打印信息:
b=com.example.core.mydemo.bean.ClassB@65b3120a
a=com.example.core.mydemo.bean.ClassA@6f539caf

posted on 2024-11-20 19:11  oktokeep  阅读(4)  评论(0编辑  收藏  举报