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");
    }


}
  • Вопрос задан
  • 308 просмотров
Решения вопроса 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 не будет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы