問題の説明
私が作成したコントローラー クラスで @Validated アノテーションを使用すると、リクエストでエラーが報告されることがわかりました。「this.classificationService のため、「com.firmSaas.business.service.DetectionIndexClassificationService.get(java.lang.Long)」を呼び出せません」 " 無効である
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 フレームワークが DetectionIndexClassificationService インスタンスを正しく挿入していないことが原因です。
ただし、 @Validated アノテーションはパラメーターの検証のみを有効にし、依存関係の注入には直接影響しないため、通常はこのエラーは発生しません。
考えられる原因と解決策:
- DetectionIndexClassificationService が正しく宣言され、Spring Bean として構成されていることを確認してください。サービス クラスで @Service アノテーションを使用するか、構成ファイルで @Service アノテーションを正しく構成していることを確認してください。
- DetectionIndexClassificationService クラスがパッケージ スキャンの範囲内にあるか、Bean スキャンが手動で構成されていることを確認してください。
- 依存関係注入に Spring を使用せずにコントローラーで DetectionIndexClassificationService オブジェクトを手動で作成した場合、Spring はそれを自動的に注入できません。この場合、手動で作成したオブジェクトを削除し、@Autowired または @Resource アノテーションを使用して DetectionIndexClassificationService を挿入する必要があります。
- AOP (アスペクト指向プログラミング) が Spring 構成で使用されている場合、プロキシの問題が発生する可能性があります。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);
}
}