문제 설명
내가 작성한 Controller 클래스에서 @Validated 주석을 사용할 때 요청에서 "this.classificationService 때문에 "com.firmSaas.business.service.DetectionIndexClassificationService.get(java.lang.Long)"을 호출할 수 없다는 오류가 보고되는 것을 발견했습니다. "은(는) null입니다.
package com.firmSaas.business.web;
import com.firmSaas.business.bean.dto.DetectionIndexClassificationDTO;
import com.firmSaas.business.bean.vo.DetectionIndexClassificationVO;
import com.firmSaas.business.service.DetectionIndexClassificationService;
import com.firmSaas.core.bean.WrapMapper;
import com.firmSaas.core.bean.Wrapper;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
@RestController
//当使用此注解时就会导致报错,而删除此注解时则一切正常
@Validated
@RequestMapping("/detectionIndexClassification")
public class DetectionIndexClassificationController {
@Resource
private DetectionIndexClassificationService classificationService;
@PostMapping("/add")
@ApiOperation(value = "批量新增检测指标分类")
private Wrapper<?> add(@Valid @RequestBody List<DetectionIndexClassificationDTO> indexClassificationDTOList){
System.out.println(classificationService);
classificationService.add(indexClassificationDTOList);
return WrapMapper.ok();
}
@PostMapping("/update")
@ApiOperation(value = "根据ID更新检测指标分类")
private Wrapper<?> update(@Valid @RequestBody DetectionIndexClassificationDTO indexClassificationDTO){
classificationService.update(indexClassificationDTO);
return WrapMapper.ok();
}
@DeleteMapping("/delete/{id}")
@ApiOperation(value = "根据ID删除检测指标分类")
private Wrapper<?> delete(@PathVariable Long id){
classificationService.delete(id);
return WrapMapper.ok();
}
@GetMapping("/get/{platformId}")
@ApiOperation(value = "获取所有的检测指标分类")
private Wrapper<List<DetectionIndexClassificationVO>> get(@PathVariable Long platformId){
List<DetectionIndexClassificationVO> detectionIndexClassificationVOS = classificationService.get(platformId);
return WrapMapper.ok(detectionIndexClassificationVOS);
}
}
원인 분석:
오류 메시지에 따르면 @Validated 주석을 사용하면 this.classificationService 개체가 비어 있게 되는데, 이는 일반적으로 Spring 프레임워크가 탐지 인덱스ClassificationService 인스턴스를 올바르게 주입하지 않기 때문에 발생합니다.
그러나 @Validated 주석은 매개변수 유효성 검사만 활성화하고 종속성 주입에 직접적인 영향을 주지 않으므로 일반적으로 이 오류를 발생시키지 않습니다.
가능한 원인 및 해결 방법:
- DetectionIndexClassificationService가 Spring Bean으로 올바르게 선언 및 구성되었는지 확인하세요. 서비스 클래스에서 @Service 주석을 사용하거나 구성 파일에서 올바르게 구성했는지 확인하세요.
- DetectionIndexClassificationService 클래스가 패키지 검색 범위 내에 있는지 확인하거나 Bean 검색이 수동으로 구성되어 있는지 확인하세요.
- 종속성 주입을 위해 Spring을 사용하지 않고 컨트롤러에서 탐지 인덱스ClassificationService 객체를 수동으로 생성하면 Spring이 자동으로 이를 주입할 수 없습니다. 이 경우 수동으로 생성된 객체를 삭제한 후 @Autowired 또는 @Resource 주석을 사용하여 탐지 인덱스 클래스화 서비스를 주입해야 합니다.
- Spring 구성에서 AOP(관점 지향 프로그래밍)를 사용하면 프록시 문제가 발생할 수 있습니다. AOP가 올바르게 구성되어 있고 서비스 주입에 영향을 미치지 않는지 확인하세요.
검사 결과 위의 문제로 인한 것이 아닌 것으로 확인되어 해결하는데 오랜 시간이 걸렸고, 막 머리가 아플 때 문득 문제의 핵심인 접근 한정자를 발견했습니다.
@Validated 주석이 사용되지만 개인 액세스 수정자가 컨트롤러 메서드에 추가됩니다. Spring에서는 private으로 수정된 메서드가 정상적으로 프록시되지 않아 종속성 주입이 실패하게 됩니다.
해결책:
컨트롤러 메소드 접근 한정자를 public으로 수정하세요.코드를 입력할 때 주의해야 합니다. 그렇지 않으면 이상한 문제가 발생하여 문제를 찾기가 어려워 매우 번거롭습니다.
package com.firmSaas.business.web;
import com.firmSaas.business.bean.dto.DetectionIndexClassificationDTO;
import com.firmSaas.business.bean.vo.DetectionIndexClassificationVO;
import com.firmSaas.business.service.DetectionIndexClassificationService;
import com.firmSaas.core.bean.WrapMapper;
import com.firmSaas.core.bean.Wrapper;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
@RestController
@Validated
@RequestMapping("/detectionIndexClassification")
public class DetectionIndexClassificationController {
@Resource
private DetectionIndexClassificationService classificationService;
@PostMapping("/add")
@ApiOperation(value = "批量新增检测指标分类")
public Wrapper<?> add(@Valid @RequestBody List<DetectionIndexClassificationDTO> indexClassificationDTOList){
System.out.println(classificationService);
classificationService.add(indexClassificationDTOList);
return WrapMapper.ok();
}
@PostMapping("/update")
@ApiOperation(value = "根据ID更新检测指标分类")
public Wrapper<?> update(@Valid @RequestBody DetectionIndexClassificationDTO indexClassificationDTO){
classificationService.update(indexClassificationDTO);
return WrapMapper.ok();
}
@DeleteMapping("/delete/{id}")
@ApiOperation(value = "根据ID删除检测指标分类")
public Wrapper<?> delete(@PathVariable Long id){
classificationService.delete(id);
return WrapMapper.ok();
}
@GetMapping("/get/{platformId}")
@ApiOperation(value = "获取所有的检测指标分类")
public Wrapper<List<DetectionIndexClassificationVO>> get(@PathVariable Long platformId){
List<DetectionIndexClassificationVO> detectionIndexClassificationVOS = classificationService.get(platformId);
return WrapMapper.ok(detectionIndexClassificationVOS);
}
}