春季启动 2.2.7。让我们想象下一个项目结构:
通用存储库接口:
public interface IRepository<T> {
Optional<T> get(Long id);
List<T> getALl();
T save(T t);
}
…它的实现:
@Component
public class IntegerRepository implements IRepository<Integer> {
@Override
public Optional<Integer> get(Long id) {
return Optional.of(10);
}
@Override
public List<Integer> getALl() {
return Arrays.asList(10,20,30);
}
@Override
public Integer save(Integer integer) {
return integer;
}
}
通用抽象控制器类:
public abstract class AController<T> {
private IRepository<T> repository;
public AController(IRepository<T> repository) {
this.repository = repository;
}
public Optional<T> get(Long id) {
return repository.get(id);
}
public List<T> getAll() {
return repository.getALl();
}
public T post(T t) {
return repository.save(t);
}
}
控制器接口:
@RequestMapping("/integers")
public interface IntegerController {
@RequestMapping(method = RequestMethod.GET, value = "/{id}")
Optional<Integer> get(@PathVariable Long id);
@RequestMapping(method = RequestMethod.GET)
List<Integer> getAll();
@RequestMapping(method = RequestMethod.POST)
Integer post(@RequestBody Integer t);
}
…及其实施:
@RestController
public class IntegerControllerImpl extends AController<Integer> implements IntegerController {
@Autowired
public IntegerControllerImpl(IntegerRepository repository) {
super(repository);
}
}
为什么 Spring 不映射控制器get()
和getAll()
方法,而是映射post()
?
2020-05-16 09:44:51.347 TRACE 5437 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : c.a.s.c.IntegerControllerImpl: {POST /integers}: post(Integer)
UPD。我做了一些研究,发现如果控制器子类将覆盖 GET/DELETE 方法(PUT 和 POST 运行良好),它将按预期工作。因此,由于泛型,似乎不支持这些 HTTP 方法从超类继承此类行为......但是,也许稍后我会在 spring MVC GitHub repo 上打开这个案例的问题。
@RestController
public class IntegerControllerImpl extends AController<Integer> implements IntegerController {
@Autowired
public IntegerControllerImpl(IntegerRepository repository) {
super(repository);
}
@Override
public Optional<Integer> get(Long id) {
return super.get(id);
}
@Override
public List<Integer> getAll() {
return super.getAll();
}
}
日志输出
2020-05-16 13:54:12.843 TRACE 5914 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping :
c.a.s.c.IntegerControllerImpl:
{GET /integers/{id}}: get(Long)
{GET /integers}: getAll()
{POST /integers}: post(Integer)