引用不到其他模块的依赖,如何调用引用不到依赖的方法?
在Spring框架,当父模块依赖子模块,而子模块没有依赖父模块时,子模块无法直接调用父模块中的方法。这是因为依赖关系是单向的,父模块只能访问子模块提供的接口或方法。
本文介绍了两种方法来实现子模块调用父模块的方法,包括通过依赖注入和使用事件驱动机制。通过这些方法,可以实现子模块与父模块的交互,实现更灵活的模块间通信。
问题背景
在子模块中定义一个回调接口,父模块实现该接口,并将实现类的实例传递给子模块。子模块可以通过回调接口调用父模块中的方法。
假设有两个模块:
- 父模块 (能够调用子模块的方法,引入了子模块的依赖)
- 子模块(无法调用父模块的方法,没有引入父模块依赖)
子模块 --> 父模块
现在让子模块调用父模块中的方法
两种方法
方法一:通过依赖注入实现子模块调用父模块的方法
- 在子模块中声明父模块的接口类型成员变量
- 父模块中定义bean并实现子模块的接口
- 通过Bean工厂依赖注入父模块的bean方法来间接调用父模块中的方法
方法二:使用事件驱动机制实现子模块调用父模块的方法
- 在父模块中定义一个事件类
- 子模块中监听事件该,并在事件触发时执行相的应方法
- 子模块通过触发父模块知通来事件的定义父模块执行相应的方法
方法一:接口回调+Bean工厂方式:
- 子模块新建一个接口
// 子模块中的接口
public interface ChildInterface {
void parentMethod();
}
- 父模块可以引用到子模块,所以可以实现子模块的接口。父模块新建两个bean,并实现
ChildInterface
子模块接口,这里写的就是子模块要调用那些方法和逻辑。项目启动后,会想bean工厂注册两个名字为parent1
和parent2
的bean。
// 父模块中的类
@Service("parent1")
public class Parent1Service implements ChildInterface {
public void parentMethod() {
// 实现逻辑
}
}
// 父模块中的类
@Service("parent2")
public class Parent2Service implements ChildInterface {
public void parentMethod() {
// 实现逻辑
}
}
- 注入
ChildInterface
接口,通过spring框架的bean工厂注入parent1
来调用。
// 子模块调用父模块中的方法
@Service
public class ChildServiceCaller {
//注入接口
//根据bean名字来区分调用那一个接口实现类
@Autowired
@Qualifier("parent1")
private ChildInterface childInterface;
public void callParentMethod() {
// 调用父模块中的方法
childInterface.parentMethod();
}
}
方法二:使用事件驱动(Event-driven)机制:
子模块定义一个事件,父模块监听该事件,并在事件触发时执行相应的方法。通过事件驱动机制,子模块可以间接调用父模块中的方法。例如:
-
子模块定义一个时间,父模块也可以引用到
//子模块 -- 事件 public class ChildEvent extends ApplicationEvent { ChildEvent(Object source) { super(source); } }
-
父模块,监听子模块的事件,能够引用到
ChildEvent
//父模块 -- 监听器 @Component public class ParentEventListener { @EventListener public void handleEvent(ChildEvent event) { System.out.println("ChildEvent"); } }
-
子模块触发事件,间接调用父模块的方法,无需引用父模块定义的方法和类,子模块发布一个事件,父模块的事件监听器监听到后执行业务逻辑。子模块成功调用父模块。
//子模块 -- 触发事件,间接调用父模块方法 @Service public class ChildService { @Resource private ApplicationEventPublisher eventPublisher; public void callParentMethod(){ eventPublisher.publishEvent(new ChildEvent(this)); } }
事件驱动机制并传递参数
//子模块 -- 事件
public class ChildEvent extends ApplicationEvent {
/**
* 事件
*/
public ChildEvent(Object source,String message) {
super(source);
this.message = message;
}
/**
* 承载被传递的参数
*/
private String message;
public String getMessage() {
return message;
}
}
//父模块 -- 监听器
@Component
public class ParentEventListener {
@EventListener
public void handleEvent(ChildEvent event) {
//获取参数
String message = event.getMessage();
System.out.println("ChildEvent:"+message);
}
}
//子模块 -- 触发事件,间接调用父模块方法
@Service
public class ChildService {
@Resource
private ApplicationEventPublisher eventPublisher;
public void callParentMethod(){
String message = "hello world";
eventPublisher.publishEvent(new ChildEvent(this,message));
}
}