Java Spring中抽象类的构造函数依赖注入
我想在我的应用程序中使用构造函数依赖项注入 我已创建此控制器:Java Spring中抽象类的构造函数依赖注入,java,spring,spring-boot,spring-mvc,Java,Spring,Spring Boot,Spring Mvc,我想在我的应用程序中使用构造函数依赖项注入 我已创建此控制器: public abstract class BonanzaCloudController { protected final UserService userService; protected BonanzaCloudController(UserService userService) { this.userService = userService; } ... } 还有这个
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
的子类,因此AppErrorController
的构造函数必须调用BonanzaCloudController
的构造函数(根据java定义的规则)
因此,AppErrorController
的构造函数必须是
public AppErrorController(UserService userService, ErrorAttributes errorAttributes, EmailService emailService) {
super(userService);
this.errorAttributes = errorAttributes;
this.emailService = emailService;
}
尽管
userService
不必是第一个参数,但只有super()
调用必须是第一个参数。这不是Spring DI的问题,而是类层次结构的问题。要构造一个AppErrorController
,JVM将需要构造其超类的一个基本实例,但您还没有为它提供这样做的方法。您需要创建一个默认构造函数或显式调用super(…)
并传递UserService
的实例。这与Spring无关。它是Java
您拥有基类BonanzaCloudController
。使用1个参数在那里声明构造函数,意味着没有参数构造函数将不再存在:
protected BonanzaCloudController(UserService userService) { }
现在您有了一个子类:
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;
}
}
上面的代码中有我的小注释。创建子类的实例时,首先调用基类构造函数来实例化对象的“基”部分。在我们的例子中,它是super()这里它指的是基类中的无arg构造函数
(因为它只是super()
,没有args),而基类中根本没有它
所以要解决这个问题,你基本上有两个选择。首先,可以使用基类中的param调用构造函数:
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;
}
或者,您可以不向基类添加参数构造函数,这样就根本不需要调用super。您的抽象类应该在层次结构下有一个实现。如果您的抽象类是这里唯一的类,那么它没有任何用途,因为JVM无法创建它的实例。