Używam Spring AOP, a zatem pośrednio CGLIB w moim kontroler Spring MVC. Od CGLIB potrzebuje domyślnego konstruktora włączyłem jeden i mój kontroler teraz wygląda tak:Jak zapobiec ostrzeżeniom o błędnych błędach przy korzystaniu z CGLIB/Spring AOP?
@Controller
public class ExampleController {
private final ExampleService exampleService;
public ExampleController(){
this.exampleService = null;
}
@Autowired
public ExampleController(ExampleService exampleService){
this.exampleService = exampleService;
}
@Transactional
@ResponseBody
@RequestMapping(value = "/example/foo")
public ExampleResponse profilePicture(){
return this.exampleService.foo(); // IntelliJ reports potential NPE here
}
}
Problem jest teraz, że analiza statyczna kodu IntelliJ IDEA donosi potencjalny NullPointerException, ponieważ this.exampleService
może być null.
Moje pytanie brzmi:
Jak uniknąć tych fałszywych pozytywnych ostrzeżenia NULL? Jednym rozwiązaniem byłoby dodanie assert this.exampleService != null
lub może użyć Guawa Preconditions.checkNotNull(this.exampleService)
.
Należy to jednak dodać do każdej metody dla każdego pola użytego w tej metodzie. Wolałbym rozwiązanie, które mógłbym dodać w jednym miejscu. Może adnotacja na domyślnym konstruktorze czy coś takiego?
EDIT:
wydaje się być mocowane za pomocą sprężyny 4, jednak obecnie używam Spring 3: http://blog.codeleak.pl/2014/07/spring-4-cglib-based-proxy-classes-with-no-default-ctor.html
Czy ten konstruktor rzeczywiście musi być wywoływalny, czy po prostu musi istnieć? Czy możesz rzucić wyjątek? – chrylis
Jedną z opcji jest użycie AspectJ weaver w czasie kompilacji lub środowiska wykonawczego, a nie cglib. Spring docs wyjaśniają, jak to zrobić. Jedną z korzyści tego podejścia jest to, że pozwala on na iniekcję zależności i oprzyrządowanie obiektów domen, które zwykle są "anemiczne". Innym jest wspieranie klas, które będą wyposażone w interfejs, i dlatego używają dynamicznego proxy zamiast cglib - w zależności od charakteru klasy może to być dobra praktyka. –
Czy problem nadal występuje, gdy występuje 'setter' dla' exampleService'? – 11thdimension