ejb Name Environment

关于EJB3.x的命名空间一直都很迷惑,阅读规范以后这里作一下笔记:java

EJB reference,是指一个EJB引用另外一个EJB的business interface, non-interface views或者home接口。ios

咱们能够在部署描述符ejb-jar.xml中:web

一、在同一ejb-jar.xml中一个EJB对另外一个EJB的引用,所以大多数状况下,。服务器

二、同一应用(企业应用)中一个EJB对另外一个EJB的引用(它们在不一样的ejb-jar.xml中被声明)。app

三、java:global中的引用(这一点为何规范中没有说?)。less

 

JAVAEE中EJB的JNDI有下面几个命名空间:ide

java:globalflex

java:appui

java:modulethis

java:comp

 

每一个Bean拥有本身的java:comp,Bean与Bean之间java:comp是相互隔离的,一样module与module之间的java:module是相互隔离的,应用与应用之间java:app是相互隔离的。另外打包在war中的Bean比较特殊,全部的web组件(servlet/filter)与全部的Bean(包括Bean与Bean之间)共用同一个java:comp空间。

 

<ejb-link>在下面的状况下会使用:

Here are some scenarios that hopefully clarify why <ejb-link/> (or @EJB(beanName="...")) and EJB ref bindings are both useful and complementary:

    An application can itself be logically broken up into components, and the developer chooses to use EJBs to implement those components. In this case, the application developer knows the target EJB component that the client wants to use. If there are multiple components implementing the same interface, then some disambiguation is required, and <ejb-link/> can be used.

    An application has a dependency on an external service. In this case, the application knows it has a dependency on an external service, so <ejb-link/> cannot be used since the service implementation does not exist in the same application.

    An application has a dependency on an external service, but a minimal implementation is provided in the same application. In this case, the developer might use an <ejb-link/> as in #1, but the deployer has the flexibility to override that choice as in #2.


<resource-ref>和<resource-env-ref>

<resource-ref>与<resource-env-ref>本质上没有太大的区别:

一、他们都使用@Resource注解来标记,有些类型甚至还能够互换。

二、<resource-ref>与<resource-env-ref>不一样之处在于,<resource-ref>是指引用咱们在JavaEE应用服务器上配置的资源,好比jdbc,ConnectionFacotry等等这一类型的资源,一般来讲这些资源具备Factory性质,固然不是Factory性质也能够,这没有明确的规定,有一些资源应用服务器会进行特殊处理,好比ConnectionFactory之类的。

但<resource-env-ref>通常是指引用咱们应用服务器的组件,好比下面这些类型,它们不少是bean运行时涉及的上下组件,也有一些像Queue,Topic之类的配置性资源,它们大部分是直接的组件(非factory性质):

    public static final Set<String> knownResourceEnvTypes = new TreeSet<String>(Arrays.asList(
        "javax.ejb.EJBContext",
        "javax.ejb.SessionContext",
        "javax.ejb.EntityContext",
        "javax.ejb.MessageDrivenContext",
        "javax.transaction.UserTransaction",
        "javax.jms.Queue",
        "javax.jms.Topic",
        "javax.xml.ws.WebServiceContext",
        "javax.ejb.TimerService",
        "javax.enterprise.inject.spi.BeanManager",
        "javax.validation.Validator",
        "javax.validation.ValidatorFactory"
    ));

 下面有是JavaEE规范对<resource-env-ref>的描述:

This section describes the programming and deployment descriptor interfaces that 
allow the Application Component Provider to refer to administered objects that are 
associated with a resource (for example, a Connector CCI InteractionSpec 
instance) by using “logical” names called resource environment references. The 
resource environment references are special entries in the application component’s 
environment. The Deployer binds the resource environment references to 
administered objects in the target operational environment.

 

相似的还有@PersistenceContext,@PersistenceUnit:

@PersistenceContext用于注入/引用 EntityManager

@PersistenceUnit用于注入EntityManagerFactory

 

 glassfish中的mappedName并非指将ejb映射到java:global下,而是指全局jndi,全局jndi跟java:global并非一个东西,并且从glassfish的jndi结构上来看,java:global只是全局jndi下面的一个子context。

 

在EJB中咱们一般称JNDI为ENC,也就是Enterprise Naming Context的缩写。

resource-ref的ref-name:指程序代码中所使用的进行lookup的jndi name,若是咱们不指定它所注入资源的jndi名称,则默认注入名为java:comp/env/full-qualified.class.name/member的资源。

resource-ref的mapped-name:指所引用的外部(全局)的资源的id。

resource-env-ref与resource-ref差很少,但resource-env-ref是直接的资源,针对 queue 和topic这一类的。

new InitialContext()的时候,这个InitialContext并不必定是指向java:comp/env,有的应用服务器会指向这个位置,但规范里面并无这个规定,由于这样子的程序并非portable的。好比Tomcat的InitialContext就不是(今天同事遇到这个问题了)。

ejb-ref(@Remote类型的接口/View引用), ejb-local-ref(Local类型的接口/View引用),(区别于env-entry,env-entry只能声明基本类型的引用如string, int, boolean等):

能够往bean的NamingContext(也就是java:comp命名空间下面)bind其它bean的reference。这样子咱们能够lookup到这些引用,并在适当的时候能够经过修改ejb-jar.xml来改变bean的引用,而不须要去修改代码。

ejb规范建议,bean全部的对其它bean的引用都应该位于java:comp/env/ejb下面。但经过注解所声明的引用将不会在任何subContext下面。

另外,咱们还可使用注解来进行声明ejb-ref,以下:

@EJB(name="ejb/EmplRecord", beanInterface=EmployeeRecordHome.class)
@Stateless public class EmployeeServiceBean 
implements EmployeeService {
    public void changePhoneNumber(...) {
        ...
        // Obtain the default initial JNDI context.
        Context initCtx = new InitialContext();
        // Look up the home interface of the EmployeeRecord
        // enterprise bean in the environment.
        Object result = initCtx.lookup(
        "java:comp/env/ejb/EmplRecord");
        // Convert the result to the proper type.
        EmployeeRecordHome emplRecordHome = (EmployeeRecordHome)
        javax.rmi.PortableRemoteObject.narrow(result,
        EmployeeRecordHome.class);
        ...
    }
}

 

ejb-ref-name就是咱们要绑定到java:comp下面的jndi名字,咱们进行lookup的时候须要用这个name进行lookup,

ejb-ref-type是可选填写的,能够是Entity/Session

home/remote/local-home/local用于指定引用bean的接口类型,若是引用ejb2.x的bean的话,home是必须指定的。

ejb-link/lookup-name用于指定所引用的外部bean(target)。二者不能同时使用,ejb-link是可选的,若是不填写的话,则在当前的ejb-jar.xml(包括注解)中查找具备相应接口的bean。ejb-link的值是须要引用的bean的<ejb-name>,固然也能够用注解来进行声明 。

与<ejb-ref>/<ejb-local-ref>相对应的注解是@EJB

@EJB.name => <ejb-ref-name>

@EJB.beanName => <ejb-link>

@EJB.lookup => <lookup-name>

@EJB.mappedName => <mapped-name>

 

EJB的home接口的实现由JavaEE应用服务器提供,用户只须要提供接口。其中建立bean的方法必须是create<METHOD>(xxx,xxx)的形式,Stateless Session Bean只能是create(),而对于Stateful Session Bean而言,建立Bean实例后,服务器将会去调用Bean实例上的ejbCreate<Method>方法。

相关文章
相关标签/搜索