我有一个类型化的抽象RestController,其中包含一些用于处理该类型的所有对象的通用逻辑。通过构造函数提供处理服务。
在子类的Bean实例化期间,两个构造函数均使用非null参数调用,并且成功传递了超类非null断言。
调用API端点(URI路径是子类和超类路径的组合)会调用正确的方法,并带有正确标识的参数。但是,终结点方法抛出空指针异常,因为提供的服务(通过非空断言的服务)为空。检查后,调用方法的bean的子类和超类的所有属性都报告所有属性为null。
这是一个简化的示例:
模型:
public class Cookie {
public long id;
}
public class ChocolateCookie extends Cookie {
public long chipCount;
}
服务:
public interface CookieService<T extends Cookie> {
T findCookie(long cookieId);
void eatCookie(T cookie);
}
@Service
public class ChocolateCookieService implements CookieService<ChocolateCookie> {
@Override
public ChocolateCookie findCookie(long cookieId) {
// TODO Load a stored cookie and return it.
return new ChocolateCookie();
}
@Override
public void eatCookie(ChocolateCookie cookie) {
// TODO Eat cookie;
}
}
休息控制器:
public abstract class CookieApi<T extends Cookie> {
private final CookieService<T> cookieService;
public CookieApi(CookieService<T> cookieService) {
this.cookieService = cookieService;
Assert.notNull(this.cookieService, "Cookie service must be set.");
}
@PostMapping("/{cookieId}")
public ResponseEntity eatCookie(@PathVariable long cookieId) {
final T cookie = cookieService.findCookie(cookieId); // Cookie service is null
cookieService.eatCookie(cookie);
return ResponseEntity.ok();
}
}
@RestController
@RequestMapping("/chocolateCookies")
public class ChocolateCookieApi extends CookieApi<ChocolateCookie> {
@Autowired
public ChocolateCookieApi(ChocolateCookieService cookieService) {
super(cookieService);
}
@PostMapping
public ResponseEntity<ChocolateCookie> create(@RequestBody ChocolateCookie dto) {
// TODO Process DTO and store the cookie
return ResponseEntity.ok(dto);
}
}
需要注意的是,如果我没有为超类提供服务对象,而是定义了一种抽象方法来按需获取服务并在子类中实现,则超类将按预期运行。
在公式中不包括@RestController和@RequestMapping的任何情况下,该原理均适用。
我的问题有两个:
编辑1:
我尝试重新创建该问题,但是所提供的代码按人们的建议工作正常。在篡改了简化的项目之后,我终于设法重现了这个问题。重现此问题的实际条件是子类必须无法访问超类中的终结点方法(例如:类位于不同的程序包中,并且该方法具有程序包可见性)。这将导致spring创建一个具有零填充字段的EnhancerBySpringCGLIB代理类。
修改超类方法以具有受保护/公共可见性可以解决此问题。
尼古拉
我不确定为什么您的代码无法在您的系统中运行,我在项目中创建了相同的类,并且运行良好,甚至添加了另一个Cookie类型,服务和api类。
SpringBoot日志(您可以看到已初始化的4个端点):
2019-02-26 14:39:07.612 INFO 86060 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/chocolateCookies],methods=[POST]}" onto public org.springframework.http.ResponseEntity<cookie.ChocolateCookie> cookie.ChocolateCookieApi.create(cookie.ChocolateCookie)
2019-02-26 14:39:07.613 INFO 86060 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/chocolateCookies/{cookieId}],methods=[POST]}" onto public org.springframework.http.ResponseEntity<?> cookie.CookieApi.eatCookie(long)
2019-02-26 14:39:07.615 INFO 86060 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/oatmeal-raisin-cookie],methods=[POST]}" onto public org.springframework.http.ResponseEntity<cookie.OatmealRaisinCookie> cookie.OatmealRaisingCookieApi.create(cookie.OatmealRaisinCookie)
2019-02-26 14:39:07.615 INFO 86060 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/oatmeal-raisin-cookie/{cookieId}],methods=[POST]}" onto public org.springframework.http.ResponseEntity<?> cookie.CookieApi.eatCookie(long)
如@Domingo所述,您的应用程序中可能会遇到一些配置问题,因为从OOP和Spring IoC的角度来看,您的代码看起来很好并且可以正常运行。
注意:我正在使用SpringBoot 2.0.5,Java 8,Eclipse运行这些控制器
我在GitHub上发布了我的项目,以供您参考。https://github.com/karl-codes/cookie-monster
干杯!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句