依赖注入和循环依赖注入
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