Невозможно Autowire

Использование Spring Initializer для создания простой загрузки Spring. Я выбираю DevTools только из доступных опций.

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

Теперь, когда я пытаюсь выполнить автоматическое подключение в проекте, это просто не работает. Я не понимаю. Я просмотрел все предыдущие вопросы здесь, в которых есть решения для этого, но ни один из них не работает, плюс нет ничего сложного в том, что я делаю в моем случае, а именно. Пожалуйста, посоветуйте, что мне не хватает.

@SpringBootApplication
public class DemoApplication {

    //  @Autowired
    //  private static Maker maker; // Stopped using this cos I wanted to check if the autowiring is not working in this class only or anywhere. Turns out it is anywhere. 

        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
            Maker maker = new Maker();
            maker.printName(); // Fails cos of ServiceHelper Autowiring 
        }
    }


@Service
public class Maker {

    @Autowired
    private ServiceHelper serviceHelper;

    public void printName(){
        System.out.println("This is from the method body itself.");
        System.out.println("Auto wiring works cos I got this -> " + serviceHelper.help());
    }
}

@Component
public class ServiceHelper {
    public String help(){
        return "...FROM HELPER...";
    }
}

Трассировки стека

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) Caused by: java.lang.NullPointerException at com.example.demo.services.Maker.printName(Maker.java:15) at com.example.demo.DemoApplication.main(DemoApplication.java:17) ... 5 more

Вы не можете автоматически подключать статические поля.

Darren Forsythe 18.08.2018 16:35

@DarrenForsythe Я закомментировал статическое поле.

kang 18.08.2018 16:37

@kang проверьте мой ответ, чтобы обойтись с внедрением зависимостей в статическое поле.

Fullstack Guy 18.08.2018 17:20
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
611
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы сами создаете экземпляр, его ServiceHelper не подключается автоматически Spring:

Maker maker = new Maker();

Вы можете получить доступ к bean через ApplicationContext:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext cts = SpringApplication.run(DemoApplication.class, args);
        Maker maker = ctx.getBean(Maker.class);
        maker.printName();
    }
}

Какое здесь решение, чтобы заставить работать автоматический провод?

kang 18.08.2018 16:45

Это означает, что ServiceHelper не будет автоматически подключаться к Maker, потому что Maker не добавлен в контекст приложения Spring. Maker создается с использованием ключевого слова new. Spring этого не знает.

Hima 18.08.2018 16:49

@ Хима, я понял. Я спрашиваю, как решить эту проблему, если я хочу вызвать Maker в основном методе? Невозможно использовать статический Autowire, невозможно использовать «новый», какое здесь решение?

kang 18.08.2018 16:50

вы можете проверить мой ответ, есть несколько способов статических bean-компонентов @Autowire @kang

Deadpool 18.08.2018 16:53
Ответ принят как подходящий

Если вы создаете любой bean-компонент с использованием ключевого слова new, этот bean-компонент не будет добавлен в Spring Application Context, и это один из способов статических bean-компонентов @Autowire.

@SpringBootApplication
public class DemoApplication {

    @Autowired
    private static Maker maker; 

    @Autowired
    private Maker tMaker;

    @PostConstruct
    public void init() {
    DemoApplication.maker = tMaker;
}

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        maker.printName();  
    }
}

или вы можете сделать Autowire с помощью Constructor, экземпляр Maker вводится в качестве аргумента в конструктор при создании DemoApplication

@Autowired
public DemoApplication(Maker maker) {
    DemoApplication.maker = maker;
    }

или вы можете использовать @Autowired в методе установки, метод установки вызывается с экземпляром Maker при создании DemoApplication

@Autowired
public void setMaker(Maker maker) {
        DemoApplication.maker = maker
}

Это определенно работает. Хотя я думал, что статическая автоматическая проводка невозможна на основе приведенного выше комментария, но это, похоже, доказывает, что это возможно.

kang 18.08.2018 16:55

Есть еще и другие способы @kang

Deadpool 18.08.2018 16:56

Автоподключение на статическое поле бессмысленно. Что здесь происходит, так это то, что вы автоматически подключаете второй Maker, поле экземпляра, и устанавливаете его после bean-компонента как инициализированный.

Darren Forsythe 18.08.2018 17:54

обновил другой подход, я просто предоставляю подходы для статических beans @DarrenForsythe

Deadpool 18.08.2018 18:01

Когда вы используете new Maker(), вы не используете bean-компонент Spring, созданный для вас, и в результате имеющийся у вас объект не инициализируется, поскольку зависимости не внедряются.

Вам нужно получить bean-компонент, созданный фреймворком Spring, как я сделал ниже, поскольку напрямую вы не можете автоматически связывать статические поля:

@SpringBootApplication
public class DemoApplication {

    private static Maker maker;

    @Autowired
    public void setMaker(Maker maker) {
        DemoApplication.maker = maker;
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        maker.printName();
    }
}

Другие вопросы по теме