Spring. Почему не происходит инъекция зависимости с помощью @autowired?

Есть:
MyService1.java
package a.b;

import org.springframework.stereotype.Service;

@Service
public class MyService1 {

    public void doSmth(String s) {
        System.out.println(s);
    }
}

MyService2.java
package a.b.c;

import a.b.MyService1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service
@Scope("prototype")
public class MyService2 {

    @Autowired
    private MyService1 myService1;

    public MyService2() {
        myService1.doSmth("ewg");
    }


}


TestApplication.java
package a.b.c;

import a.b.c.MyService2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;



@SpringBootApplication
public class TestApplication {

	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);

		ApplicationContext ctx
				= new AnnotationConfigApplicationContext(TestApplication.class);

		MyService2 myService2 = ctx.getBean(MyService2.class);
	}
	
}


В сервисе 2 не происходит инъекция зависимости сервиса 1, и при запуске вылетает NullPointerException
при обращение к нему

public MyService2() {
        myService1.doSmth("ewg");
    }


pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>a.b</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.1.6.RELEASE</version>
        </dependency>

    </dependencies>


</project>


Почему инъекции зависимости не проиходит? При условии, что так работает она выполняется:
MyService2.java
package a.b.c;

import a.b.MyService1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service
@Scope("prototype")
public class MyService2 {

    public MyService2(MyService1 myService1) {
        myService1.doSmth("ewg");
    }


}
  • Вопрос задан
  • 70 просмотров
Решения вопроса 2
NeoIsNotTheOne
@NeoIsNotTheOne Автор вопроса
Ответ такой, когда конструктор сервиса 2 вызывает сервис 1, его ещё не существует, так как Spring "вживляет" зависимость, после его создания, и закономерно возникает NullPointerException.
Получается, что если использовать зависимость в конструкторе, то важно чтобы "вживлялась" эта зависимость через конструктор.
ackage a.b.c;

import a.b.MyService1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service
@Scope("prototype")
public class MyService2 {

    public MyService2(MyService1 myService1) {
        myService1.doSmth("ewg");
    }


}


Или так тоже будет работать:
package a.b.c;

import a.b.MyService1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service
@Scope("prototype")
public class MyService2 {

    @Autowired
    private MyService1 myService1;

    public void doSmth() {
        myService1.doSmth("");
    }
}
Ответ написан
@Bonce
Попробуй код из конструктора вынести в метод, аннотированный
PostConstruct
. Тогда у тебя получится, так называемый, двухфазный конструктор и NPE не будет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Unitarius Москва
от 130 000 до 180 000 руб.
JTC Рязань
от 80 000 до 110 000 руб.
Rubbles (SBDA Group) Москва
от 100 000 до 200 000 руб.