N
N
NEO not chosen2019-08-15 11:35:38
Java
NEO not chosen, 2019-08-15 11:35:38

Spring. Why doesn't dependency injection happen with @autowired?

Is:
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);
  }
  
}

Service 2 does not dependency injection on service 1 and throws a NullPointerException on startup
when accessing it
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>

Why doesn't dependency injection work? Provided that this is how it works, it is executed:
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");
    }


}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
NEO not chosen, 2019-08-15
@NeoIsNotTheOne

The answer is that when service 2's constructor calls service 1, it doesn't exist yet, because Spring injects the dependency after it's created, and a NullPointerException naturally occurs .
It turns out that if you use a dependency in a constructor, it is important that this dependency is "implanted" through the constructor.

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


}

Or this will also work:
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("");
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question