1

春季启动 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)

此示例 GitHub

4

1 回答 1

0

我做了一些额外的研究,调试了 Spring,发现在这种特殊情况下 RequestMappingHandlerMapping bean 不能解析签名纯泛型返回类型中没有的方法。不能确定是反射故障/功能还是 Spring 处理程序的逻辑。不过,我在 Spring 存储库上打开了一个问题。

于 2020-05-17T08:45:06.163 回答