EJB3.0依赖注入



EJB3.0依赖注入

依赖注入又称控制反转(IOC),在Spring中我们已经有了一定的了解.依赖注入很大的简化了程序的复杂性. 这篇文章总结在EJB中怎么通过容器来完成Bean的注入.

首先看需要被注入的Bean.

 

  1. //Bean接口
  2. public interface HelloWorld {
  3.     String sayHello(String str);
  4. }
  5.  //实现
  6. @Stateless()
  7. @Remote
  8. public class  HelloWorldBean implements HelloWorld {
  9.      @Override
  10.      public String sayHello(String str) {
  11.         return ”Hello:” + str;
  12.     }
  13. }

 

 

如果不用依赖注入,我们取得bean的方式就是手动通过JNDI进行查找,代码如下:

  1.  //通过JNDI来获取HelloWorld
  2. public interface  Jndi {
  3.     public String sayHello();
  4. }
  5. @Stateless
  6. @Remote
  7. @RemoteBinding(jndiBinding= ”com/jndi”)
  8. public class  JndiBean implements Jndi {
  9.     @Override
  10.     public String sayHello() {
  11.         HelloWorld helloworld =getHelloWorld();
  12.         returnhelloworld.sayHello(“jndi”);
  13.     }
  14.     public HelloWorld  getHelloWorld() {
  15.         try {
  16.             InitialContext ctx = newInitialContext();
  17.             HelloWorld helloworld =(HelloWorld) ctx
  18.                     .lookup(“HelloWorldBean/remote”);//通过jndi来获取HelloWorld
  19.             return helloworld;
  20.         } catch (NamingException e) {
  21.             e.printStackTrace();
  22.         }
  23.         return null;
  24.     }
  25. }

 

 

这些方法中使用JNDI的语句不好理解,与业务无关,而且容易误导。

依赖注入与JNDI相反,依赖注入让只需要我们声明依赖,当需要请求资源时,由java EE容器处理资源或服务的实例化和初始化。基于使用注释或部署描述符的资源声明.

简单来说,JNDI和依赖注入的操作方向不一样,JDNI是我么自己去找Bean,而依赖注入是由容器将我们需要的Bean注入推送给我们.下面这张图说明了JNDI与依赖注入的区别.

 

 

下面来看通过注解使用依赖注入方式获取Bean的方法

一.通过@EJB()注解来存取

 

  1. //接口
  2. public interface Injection {
  3.     String sayHello();
  4. }

 


 

 

(1)第一种方式:使用beanName属性指定EJB的类名(不带包名)

 

  1. @Stateless
  2. @Remote
  3. @RemoteBinding(jndiBinding= ”com/injection”)
  4. public class  InjectionBean implements Injection {
  5.     @EJB(beanName=”HelloWorldBean”)//beanName指定EJB的名称(如果@Stateless或@Stateful没有设置过name属性,默认为不带包名的类名)
  6.     private HelloWorld helloworld;
  7.     @Override
  8.     public String sayHello() {
  9.         return helloworld.sayHello(“依赖注入”);
  10.     }
  11. }

 

 

(2)第二种方式:使用注入对象的setter方法,在第一次使用之前进行注入

 

  1. @Stateless
  2. @Remote
  3. @RemoteBinding(jndiBinding= ”com/injection”)
  4. public class  InjectionBean implements Injection {
  5.     private HelloWorld helloworld;
  6.     @EJB(beanName =”HelloWorldBean”)//容器会在属性第一次使用之前,自动的用正确的参数调用bean的Setter方法
  7.     public void setHelloWorld(HelloWorldhelloworld) {
  8.         this.helloworld = helloworld;
  9.     }
  10.     @Override
  11.     public String sayHello() {
  12.         return helloworld.sayHello(“注入者”);
  13.     }
  14. }

 

(3)第三种方式: 使用mappedName指定Bean实例的JNDI名

 

  1. @Stateless
  2. @Remote
  3. @RemoteBinding(jndiBinding= ”com /injection”)
  4. public class  InjectionBean implements Injection {
  5.     @EJB(mappedName=” HelloWorldBean/remote”)//mappedName指定EJB的全局JNDI名
  6.     private HelloWorld helloworld;
  7.     @Override
  8.     public String sayHello() {
  9.         return helloworld.sayHello(“注入者”);
  10.     }
  11. }

 

 

二. 通过@ Resource ()注解来存取

@EJB 注解只能注入EJB存根对象,除@EJB 注释之外,EJB 3.0 也支持@Resource注释来注入来自JNDI 的任何资源。

如果JNDI 对象在本地(java:comp/env)JNDI目录中,我们只需给定他的映谢名称即可,不需要带前缀

如下面例子注入一个消息connection factory和一个messaging  queue

 

  1. @Resource(mappedName=”ConnectionFactory”)
  2. QueueConnectionFactoryfactory;
  3. @Resource(mappedName=”queue/A”)
  4. Queue queue;