Я использую Spring AOP и поэтому косвенно CGLIB в моем контроллере Spring MVC. Поскольку CGLIB нужен конструктор по умолчанию на меня включен один и мой контроллер теперь выглядит следующим образом:Как предотвратить ложные положительные предупреждения указателя нулевой точки при использовании 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
}
}
Проблема теперь в том, что статический анализ кода IntelliJ IDEA сообщает потенциальному NullPointerException, поскольку this.exampleService
может быть пустым.
Мой вопрос:
Как предотвратить эти ложные положительные предупреждения нулевой указатель? Одним из решений было бы добавить assert this.exampleService != null
или, возможно, использовать Guava's Preconditions.checkNotNull(this.exampleService)
.
Однако это необходимо добавить к каждому методу для каждого поля, используемого в этом методе. Я бы предпочел решение, которое я мог бы добавить в одном месте. Может быть, аннотация по конструктору по умолчанию или что-то еще?
EDIT:
Кажется быть исправлено с весны 4, однако я в настоящее время использую Spring 3: http://blog.codeleak.pl/2014/07/spring-4-cglib-based-proxy-classes-with-no-default-ctor.html
Должен ли этот конструктор быть вызываемым, или он просто должен существовать? Не могли бы вы исключить из него исключение? – chrylis
Одним из вариантов является использование искателя AspectJ во время компиляции или времени выполнения, а не cglib. Весенние документы объясняют, как это сделать. Одним из преимуществ этого подхода является то, что он позволяет осуществлять инъекцию зависимостей и инструментальные средства объектов домена, которые обычно бывают «анемичными». Другим является обратный класс, который будет оснащаться интерфейсом и, следовательно, использовать динамический прокси, а не cglib - в зависимости от характера класса это может быть хорошей практикой в любом случае. –
Проблема существует, если присутствует 'setter' для' exampleService'? – 11thdimension