![](/img/trans.png)
[英]How to test controller layer on spring-boot by autowiring service?
[英]Autowiring Generic(T) Service in Controller within Spring Boot
我对如何在 Spring Boot 2.5.0 中将通用服务自动连接到控制器有点困惑。
这是代码:
主控制器:
@RestController
@RequestMapping("/classifiers")
public class ClassifierController<T> {
protected static final Logger LOG = LoggerFactory.getLogger(UserController.class);
public final T classifierService;
protected final JwtTokenFilter jwtTokenFilter;
protected final JwtTokenUtil jwtTokenUtil;
public ClassifierController(final JwtTokenFilter jwtTokenFilter,
final JwtTokenUtil jwtTokenUtil,
final T classifierService) {
this.jwtTokenFilter = jwtTokenFilter;
this.jwtTokenUtil = jwtTokenUtil;
this.classifierService = classifierService;
}
}
扩展控制器:
@RestController
@RequestMapping("/ss01dictionary")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class SS01WasteDictionaryController
extends ClassifierController<DictionaryService> {
@Autowired
public SS01WasteDictionaryController(JwtTokenFilter jwtTokenFilter,
JwtTokenUtil jwtTokenUtil,
DictionaryService classifierService) {
super(jwtTokenFilter, jwtTokenUtil, classifierService);
}
@RequestMapping(value = "/list", method = GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> getData(@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "20") int pageSize) {
PageRequest pageable = PageRequest.of(page, pageSize);
Page<Dictionary> dictionaryDTOList = classifierService.getAllDictionaryValues(pageable);
return ResponseEntity.status(HttpStatus.OK).body(dictionaryDTOList);
}
...
主要文摘服务:
@Service
public abstract class ClassifierService {
public final JdbcTemplate jdbcTemplate;
public ClassifierService(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
protected abstract Integer count();
}
字典服务:
@Service
public class DictionaryService
extends ClassifierService {
public DictionaryService(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
public Page<DictionaryDTO> getAllDictionaryValues(Pageable page) {
List<DictionaryDTO> result = jdbcTemplate.query(GET_SQL + " LIMIT " + page.getPageSize() + " OFFSET " + page.getOffset(),
new DictionaryRowMapper());
return new PageImpl<>(result, page, count());
}
我做错了什么? 我想要具有一些抽象方法和通用控制器的通用服务。 如何自动装配 T 服务,以便我可以使用特定服务中特定控制器的方法?
如果你想在超级抽象类中抽象出控制器和服务的公共内容,那么你必须将该类标记为抽象并将这个条件在层次结构中移到较低的位置。 系统正确地抱怨它无法找到类型 T 的服务,因为该名称没有任何可搜索的内容。 如果你创建一个名为T
的类,这个问题很可能会得到解决。 现在,如何在这里使用泛型定义。 这是我如何尝试做到的。
AbstractService
AbstractService
的子类。代码如下:
package in.silentsudo.autowiregenericservicecontroller.service;
public abstract class AbstractTransporterService {
final public String supportedVersion() {
return "1.0";
}
public abstract String transport();
}
实施例1
package in.silentsudo.autowiregenericservicecontroller.service;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
@Qualifier("audioTransporterService")
public class AudioTransporterService extends AbstractTransporterService {
@Override
public String transport() {
return "transporting audio details";
}
}
实施例2
package in.silentsudo.autowiregenericservicecontroller.service;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
@Qualifier("videoTransporterService")
public class VideoTransporterService extends AbstractTransporterService {
@Override
public String transport() {
return "transporting video details";
}
}
控制器如下 AbstractController
package in.silentsudo.autowiregenericservicecontroller.controller;
import in.silentsudo.autowiregenericservicecontroller.service.AbstractTransporterService;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
public abstract class AbstractController<S extends AbstractTransporterService> {
private final S service;
public AbstractController(S service) {
this.service = service;
}
public S getService() {
return service;
}
@RequestMapping(path = "/version")
public Map<String, String> controllerVersion() {
return Map.of("type", getClass().getName(), "v", service.supportedVersion());
}
}
实施例1
package in.silentsudo.autowiregenericservicecontroller.controller;
import in.silentsudo.autowiregenericservicecontroller.service.AudioTransporterService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(path = "/audio")
public class AudioController extends AbstractController<AudioTransporterService> {
public AudioController(AudioTransporterService service) {
super(service);
}
@GetMapping
public String get() {
return getService().transport();
}
}
实施例2
package in.silentsudo.autowiregenericservicecontroller.controller;
import in.silentsudo.autowiregenericservicecontroller.service.VideoTransporterService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(path = "/video")
public class VideoController extends AbstractController<VideoTransporterService> {
public VideoController(VideoTransporterService service) {
super(service);
}
@GetMapping
public String get() {
return getService().transport();
}
}
@RestController
注释信息不会在运行时传递。 所以最好不要用同样的Service
注释超类
还有路径
正在工作,因为他们正在扩展具有/version
方法的超类
源代码https://gitlab.com/spring-boot-cloud-samples/autowire-generic-service-controller
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.