[英]Constructor Dependency Injection in Spring with abstract classes
我想在我的应用程序中使用构造函数依赖注入。
我已经创建了这个 controller:
public abstract class BonanzaCloudController {
protected final UserService userService;
protected BonanzaCloudController(UserService userService) {
this.userService = userService;
}
...
}
和这个
@Controller
public class AppErrorController extends BonanzaCloudController implements ErrorController {
private final ErrorAttributes errorAttributes;
private final EmailService emailService;
public AppErrorController(ErrorAttributes errorAttributes, EmailService emailService) {
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
...
}
但我有这个编译错误:
There is no default constructor available in BonanzaCloudController
AppErrorController
是 BonanzaCloudController 的子类,因此BonanzaCloudController
的构造函数必须调用AppErrorController
的构造BonanzaCloudController
(由 java 定义的规则)。
因此AppErrorController
的构造函数必须是
public AppErrorController(UserService userService, ErrorAttributes errorAttributes, EmailService emailService) {
super(userService);
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
虽然userService
不必是第一个参数,但只有super()
调用必须是第一个参数。
这不是 Spring DI 问题,而是 class 层次结构的问题。 要构造AppErrorController
, JVM 将需要构造其超类的基本实例,但您尚未为其提供执行此操作的方法。 您将需要创建一个默认构造函数或显式调用super(...)
并传递UserService
的实例。
这与 Spring 无关。 它是 Java。
你有基础 class BonanzaCloudController
。 你用 1 个参数声明构造函数,这意味着没有参数的构造函数将不再存在:
protected BonanzaCloudController(UserService userService) { }
现在你有了一个孩子 class:
public class AppErrorController extends BonanzaCloudController {
public AppErrorController(ErrorAttributes errorAttributes, EmailService emailService) {
// this is how your constructor looks, super is implicit there
// means that you don't need to add it, it will be there anyway.
super();
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
}
上面的代码中有我的小注释。 当创建子 class 的实例时 - 首先调用基本 class 构造函数来实例化 object 的“基本”部分。 在我们的例子中,它是super();
在这里它指的是基础 class 中的no-arg constructor
函数(因为它只是super()
,没有参数),而您的基础 class 中根本没有它。
所以要解决这个问题,你基本上有两个选择。 首先,您可以使用基础 class 中的参数调用构造函数:
public AppErrorController(ErrorAttributes errorAttributes, EmailService emailService) {
// the first call should be an explicit call of super(...)
// as a param you need instance of UserService
super(userService);
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
或者您可以将无参数构造函数添加到您的基础 class ,然后您根本不需要调用 super 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.