gpt4 book ai didi

Spring Rest Controller 继承

转载 作者:行者123 更新时间:2023-12-04 04:32:51 25 4
gpt4 key购买 nike

我有一个类型化的抽象 RestController,其中包含一些用于处理该类型的所有对象的通用逻辑。处理服务是通过构造函数提供的。

在子类的 bean 实例化过程中,两个构造函数都使用非空参数调用,并且成功传递了父类(super class)非空断言。

调用 API 端点(URI 路径是子类和父类(super class)路径的组合)调用正确的方法,并带有正确标识的参数。
但是,端点方法会引发空指针异常,因为提供的服务(通过非空断言的服务)为空。在检查其方法被调用的 bean 的子类和父类(super class)的所有属性后,报告所有属性为空。

这是一个简化的示例:

模型:

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;
}
}

休息 Controller :
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);
}
}

请注意,如果我没有为父类(super class)提供服务对象,而是定义了一个抽象方法来按需获取服务并在子类中实现它,那么父类(super class)将按预期运行。

相同的原理适用于公式中不包含 @RestController 和 @RequestMapping 的任何情况。

我的问题有两个:
  • 为什么会这样?
  • 有没有办法使用构造函数,或者至少不必为每个子类和父类(super class)所需的每个服务实现 getter 方法?

  • 编辑1:

    我尝试重新创建问题,但提供的代码按照人们的建议运行良好。在篡改了简化的项目之后,我终于设法重现了这个问题。实际 重现该问题的条件是子类 必须无法访问父类(super class)中的端点方法。 (示例:类位于不同的包中,并且该方法具有包可见性)。
    这会导致 spring 创建一个带有零填充字段的 enhancerBySpringCGLIB 代理类。

    修改父类(super class)方法以具有 protected /公共(public)可见性解决了该问题。

    最佳答案

    您可以在抽象类中定义一个抽象方法,并在每个实现上 Autowiring 正确的服务:

    public abstract class CookieApi<T extends Cookie> {

    protected abstract CookieService<T> getCookieService();

    @RequestMapping("/cookieId")
    public void eatCookie(@PathVariable long cookieId) {
    final T cookie = cookieService.findCookie(cookieId); // Cookie service is null
    this.getCookieService().eatCookie(cookie);
    }
    }

    @RestController
    @RequestMapping("/chocolateCookies")
    public class ChocolateCookieApi extends CookieApi<ChocolateCookie> {

    @Autowired
    private ChocolateCookie chocolateCookie;

    @Override
    protected CookieService<T> getCookieService() {
    return this.chocolateCookie;
    }

    @PostMapping
    public ResponseEntity<ChocolateCookie> create(@RequestBody ChocolateCookie dto) {
    // TODO Process DTO and store the cookie
    return ResponseEntity.ok(dto);
    }
    }

    关于Spring Rest Controller 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54823765/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com