Field injection with @Inject in Spring
Asked Answered
C

1

6

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>
Culliton answered 12/9, 2016 at 7:47 Comment(3)
Constructor Injection works as long as you have only one constructor with or without any annotations. So basically Spring does not recognize the @Inject at all. Do you have right dependencies on your classpath? Please post your pom.xml or build.gradleLucianaluciano
@AliDehghani You are right about pom.xml. I've noticed that I have dependency javaee-web-api with provided scope. I replaced it with javax.servlet-ap and javax.inject, and now both annotation works well. Post your answer and I'll accept it.Culliton
@VitalyVitrenko You can answer your own question as well.Zebe
L
4

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.

Lucianaluciano answered 12/9, 2016 at 8:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.