NullPointerException при автоматическом подключении к управляемому классу, отличному от Spring (POJO) - Spring Boot

Я относительно новичок в Spring Boot и внедрении зависимостей в целом, поэтому, пожалуйста, простите любые нубские вещи, которые здесь происходят. Я создаю API, и у меня возникают проблемы с внедрением зависимостей в ресурс POJO (DTO).

Когда я вызываю метод в POJO this.numComments = commentSvc.getAllForPhoto(this.getId());, я получаю исключение NullPointerException. Однако, когда я делаю это из другого компонента, управляемого пружиной, и передаю значения в конструктор, он работает нормально.

Почитав вокруг, похоже, что мне нужно что-то сделать с аспектомJ и переплетением времени загрузки, но я не уверен, как это будет выглядеть в моем коде.

По сути, мой подход выглядит примерно так:

PhotoResource.java (POJO)

public class PhotoResource extends BaseRepresentable {

   @Autowired
   CommentService commentSvc;

   private Long id;
   private Integer numComments;

   PhotoResource(PhotoEntity entity){
   super(entity);
   this.setId(entity.getId);
   this.numComments = commentSvc.getAllForPhoto(this.getId());
   }
}

CommentService.java

@Service
public class CommentService{
   public List<CommentResource> getAllForPhoto(Long photoId) {
   // code to get all comments for photo
   }
}

Application.java

@SpringBootApplication
public class Application {
   public static void main(String[] args) {
      SpringApplication.run(Application.class);
   }
}

person orangeandgrey    schedule 04.06.2017    source источник
comment
Вам было бы намного проще отказаться от не поврежденных бобов и придерживаться бобов, управляемых весной.   -  person Antoniossss    schedule 04.06.2017
comment
Это так же просто, как аннотировать этот DTO?   -  person orangeandgrey    schedule 04.06.2017
comment
Да, это будет выглядеть так   -  person Antoniossss    schedule 04.06.2017
comment
Кроме того, рекомендуется использовать внедрение конструктора, которое устраняет скрытую зависимость, вызывающую эту проблему.   -  person chrylis -cautiouslyoptimistic-    schedule 04.06.2017


Ответы (1)


Spring не введет зависимость, если вы не попросите контейнер Spring управлять компонентом. Чтобы commentSvc можно было внедрить в класс PhotoResource, вам нужно аннотировать его с помощью @Component или @Bean или @Service, например:

@Component
public class PhotoResource extends BaseRepresentable {
   @Autowired
   CommentService commentSvc;
}

И убедитесь, что пакет этого класса входит в @ComponentScan пакетов.

Кроме того, следующее не будет компилироваться:

@Service
public class CommentService(){

Вам не нужны скобки для объявления класса, это должно быть:

@Service
public class CommentService{
person Darshan Mehta    schedule 04.06.2017
comment
Спасибо, я пытаюсь сделать это сейчас, но теперь я не могу запустить приложение, потому что оно жалуется на то, что требуемый компонент типа «PhotoEntity» не может быть найден. Означает ли это, что мне нужно добавить @Component в каждый класс? Кроме того, хороший улов в скобках, это была опечатка при помещении его на SO. - person orangeandgrey; 04.06.2017
comment
Это потому, что это требуется конструктором. Измените свою архитектуру, не создавайте POJO, если в этом нет крайней необходимости, и используйте @Autowire для всего. - person Antoniossss; 04.06.2017
comment
Да, вам нужно @Autowire конструктор и аннотировать класс PhotoEntity. Кроме того, вам не нужно аннотировать все компоненты, только те, которыми управляет Spring. - person Darshan Mehta; 04.06.2017