javaspringspring-mvcjsr330

Field injection with @Inject in Spring


I've got some strange behavior in working of @Inject in Spring. This example works well:

@Controller
@RequestMapping("/")
public class HomeController {
    @Autowired
    private SomeBean someBean;

    @RequestMapping(method = GET)
    public String showHome() {
        System.out.println(someBean.method());
        return "home";
    }
}

But if I replace @Autowired with @Inject, showHome method will throw NullPointerException because someBean is null. The same thing with setter injection. But with constructor injection both @Autowired and @Inject works well.

Why does it happen?

I'm using Spring 4.3.1. My dependencies in pom.xml looks like this:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
<dependencies>

Solution

  • Spring supports JSR-330 standard annotations, you just need to put the relevant jars in your classpath. If you're using maven, add the following to your pom.xml:

    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>
    

    Why Constructor Injection Works?

    As of Spring 4.3, It is no longer necessary to specify the @Autowired annotation if the target bean only defines one constructor. Since you have only one constructor, required dependencies will be injected no matter which annotation you're using.

    Also checkout this post on why field injection is evil.