Spring 3 and JSR-330 @Inject and @Named example

Since Spring 3.0, Spring supports for the standard JSR 330: Dependency Injection for Java. In Spring 3 application, you can uses standard

  1. @Inject instead of Spring’s @Autowired to inject a bean.
  2. @Named instead of Spring’s @Component to declare a bean.

Those JSR-330 standard annotations are scanned and retrieved the same way as Spring annotations, the integration just happened automatically, as long as the following jar in your classpath.

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

1. Spring Annotations

Let see a normal Spring’s annotation example – @Autowired and @Component

P.S @Component, @Repository and @Service are same, just declares a bean in Spring Ioc context.

CustomerDAO.java
package com.mkyong.customer.dao;
 
import org.springframework.stereotype.Repository;
 
@Repository
public class CustomerDAO 
{
	public void save() {
		System.out.println("CustomerDAO save method...");
	}	
}
CustomerService.java
package com.mkyong.customer.services;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mkyong.customer.dao.CustomerDAO;
 
@Service
public class CustomerService 
{
	@Autowired
	CustomerDAO customerDAO;
 
	public void save() {
 
		System.out.println("CustomerService save method...");
		customerDAO.save();
 
	}
 
}

2. JSR-330 Annotations

Basically, it works the same, just with different annotations – @Inject and @Named.

CustomerDAO.java
package com.mkyong.customer.dao;
 
import javax.inject.Named;
 
@Named
public class CustomerDAO 
{
 
	public void save() {
		System.out.println("CustomerDAO save method...");
	}	
}
CustomerService.java
package com.mkyong.customer.services;
 
import javax.inject.Inject;
import javax.inject.Named;
 
import com.mkyong.customer.dao.CustomerDAO;
 
@Named
public class CustomerService 
{
	@Inject
	CustomerDAO customerDAO;
 
	public void save() {
 
		System.out.println("CustomerService save method...");
		customerDAO.save();
 
	}
 
}

3. Run it

Both Spring and JSR330 annotations need component scan to works.

Spring-AutoScan.xml – Scan bean automatically
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
 
    <context:component-scan base-package="com.mkyong.customer" />
 
</beans>
App.java – Run it
package com.mkyong;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.mkyong.customer.services.CustomerService;
 
public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    		new ClassPathXmlApplicationContext(new String[] {"Spring-AutoScan.xml"});
 
    	CustomerService cust = (CustomerService)context.getBean("customerService");
    	cust.save();
 
    }
}

Above two examples are generated the same output

CustomerService save method...
CustomerDAO save method...

4. JSR-330 Limitations

There are some limitations on JSR-330 if compare to Spring :

  1. @Inject has no “required” attribute to make sure the bean is injected successful.
  2. In Spring container, JSR-330 has scope singleton by default, but you can use Spring’s @Scope to define others.
  3. No equivalent to Spring’s @Value, @Required or @Lazy.

Check out this Spring references.

5. Go for JSR-330

In fact, Spring’s annotations are more powerful, but only available on Spring framework. The JSR-330 is a standard spec, and it’s supported on all J2ee environment that follow the JSR-330 spec.

For new or migration project, it’s always recommended to use JSR-330 annotations, and remember, it works on Spring 3 as well.

Download Source Code

Download it – Spring-JSR330-Example.zip (27kb)

References

  1. Spring Reference : Using JSR 330 Standard Annotations
  2. JSR 330: Dependency Injection for Java
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Pingback: Blue Coaster33()

  • Pingback: Spring: Null with @Inject | Active Intelligence()

  • Nikhilesh Reddy

    Hi mkyong,

    How should we do if we have an interface instead of a class.
    Is it the same.

    Thanks,
    Nikhil

    • Nikhilesh Reddy

      Also where is the

      (CustomerService)context.getBean(“customerService”);

      we are passing a string here and are there any restrictions here.(“customerService”).
      How is it identifying without creating any bean of id customerService.
      The question I am asking is if there is an interface and 2 concrete classes implementing .
      How would i differentiate between the beans or what should I pass for
      context.getBean(“”);
      I think I can pass a class but would really like to know what to pass for a string

      • Mohit Saluja

        public interface CustomerDAO

        @Named
        public class CustomerDAOImpl implements CustomerDAO

        public interface CustomerService

        @Named(“customerService”)
        public class CustomerServiceImpl implements CustomerService

        Rest of the things are as per example @Nikhilesh Reddy

        You need to add @Named to concrete classes and define @Named(“????”) as per your requirements

  • Ponic

    Hi,

    In my DAO I have

    @Named
    public class EmployeesDAO implements IEmployeesDAO {

    and in managedbean I have

    @Named(&quot;empMB&quot;)
    @Scope(&quot;session&quot;)
    public class EmployeesManagedBean implements Serializable {
     
             @Inject
    	IEmployeesService employeesService;
     
    public List&lt;Employees&gt; getEmpList() {
    		try {
    			empList = new ArrayList&lt;Employees&gt;();
    			empList.addAll(getEmployeesService().getEmployees());
    		} catch (Exception e) {
    			e.printStackTrace();			
    		}
    		return empList;
    	}

    but when I run my application I am getting

    java.lang.NullPointerException
    	at net.test.employees.dao.EmployeesDAO.getEmployees(EmployeesDAO.java:30)

    How can I resolve this issue?

    Thanks

  • Eduard Korenschi

    If things are indeed in Spring as you put them, then there is a BIG difference from CDI annotation interpretation.
    In CDI, by default all classes are assumed to be “injectable”, the @Named annotation being used only when a bean of that class has to be accessible in some EL-context (like jsp, jsf, etc). Otherwise, injection is Typed-based, not named-based.
    So, in order to inject some User instance into o class, you just use @Inject User user, without the need for the User class to have the @Named annotation.

  • Pingback: JSF 2 + Spring 3 integration example()

  • Miso

    When using JSR-330, why not go for typesafe javax.inject.Qualifier-based custom annotations?

    • http://www.mkyong.com mkyong

      For simple injection, @Named and @Inject are enough.