Are*_*inu 1 java rest spring dependency-injection controller
我正在编写 spring 控制器,它注入一个 bean。
\n\nbean 添加到配置中(我们使用 java 配置来完成所有操作):
\n\n@Bean\npublic NotificationService notificationService() {\n    return new NotificationService();\n}\n该服务本身几乎没有注入的依赖项和功能:
\n\npublic class NotificationService {\n\n    @Inject\n    NotificationRepository notificationRepository;\n\n    @Inject\n    ProjectRepository projectRepository;\n\n    @Inject\n    ModelMapper modelMapper;\n\n    public NotificationDto create(NotificationDto notificationDto) {\n        //convert to domain object, save, return dto with updated ID\n        return notificationDto;\n    }\n\n    public void markAsRead(Long id, String recipientNip) {\n        //find notification, update status\n    }\n}\n模型映射器几乎没有任何配置,只是设置为严格。JpaRepository同时,存储库是没有自定义功能的扩展接口。他们是由 找到的@EnableJpaRepositories。
最后我有控制器尝试使用上面的代码:
\n\n@RestController\n@RequestMapping("/notifications")\npublic class NotificationController extends ExceptionHandlerController {\n\n    @Autowired\n    private NotificationService notificationService;\n\n    @PreAuthorize("isFullyAuthenticated() and hasRole(\'create_notification\')")\n    @RequestMapping(method = RequestMethod.POST, consumes = MediaTypeExtension.APPLICATION_JSON_UTF8_VALUE)\n    public ResponseEntity<?> createNotification(@Valid @RequestBody(required = true) final NotificationDto notification) {\n        this.notificationService.create(notification);\n        final HttpHeaders headers = new HttpHeaders();\n        return new ResponseEntity<>(headers, HttpStatus.CREATED);\n    }\n\n    @PreAuthorize("isFullyAuthenticated() and hasRole(\'update_notification\')")\n    @RequestMapping(value = "/{id}/read", method = RequestMethod.PUT)\n    private ResponseEntity<?> markNotificationAsRead(@PathVariable("id") Long id, @AuthenticatedContractor ContractorDto contractor) {\n        this.notificationService.markAsRead(id, contractor.getNip());\n        final HttpHeaders headers = new HttpHeaders();\n        return new ResponseEntity<>(headers, HttpStatus.OK);\n    }\n}\n所有控制器都是根据其包通过 @ComponentScan 添加的。
\n\n正如您所看到的,这两个函数都使用notificationService. 当我发送时POST,create已正确/notifications注入notificationService。在同一个控制器中,当我PUT在 上请求时/{id}/read,notificationService是null。
我认为这与 spring 将东西放入其容器中有关,并且由于某种原因无法执行该功能。我在控制器中还有一些功能,并且所有功能notificationService都已正确注入。我没有看到createNotification和markNotificationAsRead函数之间有任何真正的区别,而且我在 google/stack 上找不到任何远程相关的东西。在所有情况下,由于配置错误,服务根本不会注入。
编辑\n我尝试更改函数中的内容,直到它开始工作。我的最终代码如下所示:
\n\n@PreAuthorize("isFullyAuthenticated() and hasRole(\'update_notification\')")\n    @RequestMapping(value = "{id}/read", method = RequestMethod.PUT)\n    public ResponseEntity<?> read(@PathVariable("id") Long id, @AuthenticatedContractor ContractorDto contractor) {\n        this.notificationService.markAsRead(id, contractor.getNip());\n\n        final HttpHeaders headers = new HttpHeaders();\n        return new ResponseEntity<>(headers, HttpStatus.OK);\n    }\n它有效。老实说,我看不出与原始代码有任何区别,并且我已经盯着它看了一个小时左右。进口的也是一样的。
\n\n我还注意到(在无法工作的代码上),虽然调试堆栈上控制器的所有函数都被标记为
\n\nNotificationController.functionName(arguments) line: x\n非工作功能是:
\n\nNotificationController$$EnhancerBySpringCGLIB$$64d88bfe(NotificationController).\xe2\x80\x8c\xe2\x80\x8bmarkNotificationAsRead(ContractorDto) line: 86\n我不知道为什么 spring CGLIB 增强了这个单一功能。我尝试过查找,但现在我两手空空。即使代码开始工作,我仍将问题悬而未决,以便找到根本原因。
\n您的方法markNotificationAsRead是私有的,这可能会导致问题。我刚刚对最终方法遇到了同样的问题 - 此消息出现在日志中:
2016-11-28 17:19:14.186  INFO 97079 --- [           main] o.s.aop.framework.CglibAopProxy          : Unable to proxy method [public final java.util.Map com.package.controller.MyController.someMethod(javax.servlet.http.HttpServletResponse)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
看起来在一种情况下我们看到了 CGLib 代理,而在另一种情况下我们看到了实际的类。其中只有一个已注入所有字段,看起来代理的所有字段均为空。但这并不重要 - 重点是您的方法应该是公共的,而不是最终的,以便通过 @PreAuthorize 方法正确代理。
| 归档时间: | 
 | 
| 查看次数: | 2358 次 | 
| 最近记录: |