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>
Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151
Vitalii Vitrenko
  • 9,763
  • 4
  • 43
  • 62
  • 1
    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.gradle` – Ali Dehghani Sep 12 '16 at 08:05
  • 2
    @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. – Vitalii Vitrenko Sep 12 '16 at 08:22
  • @VitalyVitrenko You can answer your own question as well. – Maroun Sep 12 '16 at 08:26

1 Answers1

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.

Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151