Автоматически подключаемая зависимость равна нулю

#java #spring-boot #gradle

#java #весенняя загрузка #gradle

Вопрос:

У меня есть проект spring-boot, который я смог успешно запустить на моем старом Mac под управлением Sierra. Недавно я купил новый Mac с Mojave на нем, и когда я создаю проект spring-boot, я получаю NullpointerException при попытке использовать зависимость @Autowired.

Я убедился, что создаю проект с использованием оболочки gradle (версия 4.8) и что на обеих машинах установлена одна и та же версия java (1.8.0_60). Версия spring boot, определенная в файле build.gradle, равна 1.5.5.RELEASE.

Я понимаю, что существует циклическая зависимость между классами Foo и MyService, но это никогда не было проблемой. В MyService должен быть введен Foo «до» вызова метода Foo init(), но, похоже, это не так, когда я создаю и запускаю его на новом компьютере. Я предполагаю, что каким-то образом используется другая версия spring, где правила для внедрения зависимостей каким-то образом отличаются.

 @Component
public class Foo {

   @Autowired
   private MyService service;

   @PostConstruct
   private void init() {
      service.doSomething();
   }

   public void bar() {}
}

@Component
public class MyService {

   @Autowired
   private Foo foo;

   public void doSomething() {
      foo.bar(); // <- NPE occurs here!
   }

}
  

Комментарии:

1. Чтобы избежать циклической зависимости, вы можете попросить контейнер лениво ввести одну зависимость.

2. Спасибо, @Lazy было решением. Понятия не имею, почему это сработало на старой машине.

Ответ №1:

Это определенно плохой признак того, что у вас циклическая зависимость. Вам следует изменить дизайн. Я проверял сообщение в блоге, посвященное этой теме, и в нем говорится следующее о циклических зависимостях:

 When you have a circular dependency, it’s likely you have a design problem 
and the responsibilities are not well separated. You should try to redesign 
the components properly so their hierarchy is well designed and there is no 
need for circular dependencies.

If you cannot redesign the components (there can be many possible reasons for 
that: legacy code, code that has already been tested and cannot be modified, 
not enough time or resources for a complete redesign…)...
  

Если вы все еще хотите оставить все как есть, вы можете проверить раздел 4.4. @PostConstruct о том, как они это делают, и черпать из этого вдохновение :).

Что касается того, почему она работает на одной машине, а на другой нет, для меня загадка.

Комментарии:

1. Спасибо, раздел 4.2 решил это для меня (и подробно baeldung.com/spring-lazy-annotation ). Я должен был убедиться, что использую отложенные аннотации как в Autowired, так и в Component.