EJB和Web容器中的资源或组件是如何查找的?

JavaEE中资源或组件是如何通过JNDI查找的一直都没完全弄清楚,这段时间花时间总算把它弄清楚了,总结如下:

(a).JavaEE1.5以前:

ServletA.java:

InitialContext ic=new InitialContext();
DataSource ds=(DataSource)ic.lookup("java:comp/env/jdbc/FooDS");

web.xml:

<resource-ref>
    <res-ref-name>jdbc/FooDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
</resource-ref>

sun-web.xml:

<resource-ref>
    <res-ref-name>jdbc/FooDS</res-ref-name>
    <jndi-name>jdbc/OracleDS</jndi-name>
</resource-ref>

其中sun-web.xml是厂商特定的配置文件,不是JavaEE规范要求的,主要的作用是将容器中需要用到的资源或组件与应用服务器定义的资源或组件关联,这样的配置文件包括:

GlassFish&Sun AppServer: sun-web.xml  sun-ejb-jar.xml  sun-application-client.xml

<res-ref-name> is the name of a component dependency  and is relative to java:comp/env

<jndi-name>      is the name of a physical AppServer resource and is relative to the root of the AppServer‘s global namespace

(b).从JavaEE 5开始可以使用Annotations:

@Resource(name="jdbc/FooDS")
private DataSource ds;

等同于web.xml或ejb-jar.xml文件中的如下定义

<resource-ref>
    <res-ref-name>jdbc/FooDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <injection-target>
        <injection-target-class>com.acme.ServletA</injection-target-class>
        <injection-target-name>ds</injection-target-name>
    </injection-target>
</resource-ref>

其中name属性的默认值为:

FIELD: <class-name>/<field-name>

METHOD: <class-name>/<setter-property-name>

TYPE:  No defaulting. name() is required.

例如:

@Resource
private DataSource ds;

等同于:

@Resource(name="com.acme.ServletA/ds")
private DataSource ds;

(c).可以使用mapped-name直接关联到在应用服务器上注册的资源或组件的全局名

// TYPE-level @Resource in Servlet

@Resource(name="jdbc/FooDS", type=javax.sql.DataSource.class, mappedName="jdbc/OracleDS")
public class ServletA{ ... }

等同于:

<resource-ref>
    <res-ref-name>jdbc/FooDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <mapped-name>jdbc/OracleDS</mapped-name>
</resource-ref>

使用这个功能的问题如下:

(1)不是JavaEE5规范要求必须实现的功能

(2)没有统一的格式和语法,各厂商可以自己定义

(3)可以被优先级更高的配置覆盖,annotation < standard.xml < sun-*.xml

也可以使用mapped-name发布资源或组件在应用服务器上的全局名

FooBean.java:

@Stateless(mappedName="ejb/MyFooBean")
public class FooBean implements Foo{
public String hello() { return "hello,world!/n"; }
}

MyAppClient.java:

@EJB(mappedName="ejb/MyFooBean")
private static Foo foo;

(d).对于没有使用mapped-name,同时也没有在厂商特定的配置文件中设置关联的资源或组件,应用服务器采用如下规则:

(1).Session beans & ejb-refs

jndi-name 自动设置成 Home/Business接口名

(2)[email protected], resource-ref, message-destination-ref, etc.

jndi-name 自动设置成资源的 java:comp/env名

例如:

@Resource(name="jdbc/FooDS")
private DataSource ds;

等同于sun-web.xml:

<resource-ref>
    <res-ref-name>jdbc/FooDS</res-ref-name>
    <jndi-name>jdbc/FooDS</jndi-name>
</resource-ref>
@Stateless(name="FooBean")
public class FooBean implements Foo{ .. }

等同于sun-ejb-jar.xml:

<ejb>
    <ejb-name>FooBean</ejb-name>
    <jndi-name>com.acme.Foo</jndi-name>
</ejb>
@EJB(name="ejb/Foo")
private static Foo foo;

等同于sun-application-client.xml:

<ejb-ref>
    <ejb-ref-name>ejb/Foo</ejb-ref-name>
    <jndi-name>com.acme.Foo</jndi-name>
</ejb-ref>

(e).采用Global JNDI

java:global[/<app-name>]/<module-name>/<bean-name>!<fully-qualified-interface-name>

<bean-name> corresponds to the session bean‘s EJB name.  It defaults to the unqualified name of the session bean class.

It can be explicitly specified using the name attribute of the @Stateless/@Stateful/@Singleton annotation.

Alternatively, if the ejb-jar.xml is being used to define the component, <bean-name> corresponds to the <ejb-name> element of ejb-jar.xml.

(f).如果同一个资源或组件用Annotation,javaEE规范定义的配置文件,厂商特定的配置文件中都定义了,那到底用哪个一般遵循如下优先顺序:

Annotation < javaEE规范定义的配置文件 < 厂商特定的配置文件

例如glassfish中:

@Resouce <  <resource-ref> in web.xml
<  <resource-ref> in sun-web.xml

glassfish, weblogic, websphere都遵循上面的顺序,只不过厂商特定的配置文件不同而已。

参考文档:

https://glassfish.java.net/javaee5/ejb/EJB_FAQ.html

https://glassfish.java.net/javaee5/ejb/compdependencies_xmlforum_nov15.pdf

时间: 2024-07-30 10:32:28

EJB和Web容器中的资源或组件是如何查找的?的相关文章

从读取properties文件说开去,浅谈web容器中类加载器

今天刚好有人让我写个通过读取properties连接数据库的小demo. 汗啊,普通项目中可以使用的文件读取,在web项目中总报空指针异常. 查阅了资料明白,赶紧记录下来,希望遇到此类问题的童鞋能引起重视. 废话不说,直接进入主题! 代码清单1: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java.io.InputStream; import java.util.Properties; import org.apache.log4

spring源码研究之IoC容器在web容器中初始化过程

前段时间在公司做了一个项目,项目用了spring框架实现,WEB容器是Tomct 5,虽然说把项目做完了,但是一直对spring的IoC容器在web容器如何启动和起作用的并不清楚.所以就抽时间看一下spring的源代码,借此了解它的原理. 我们知道,对于使用Spring的web应用,无须手动创建Spring容器,而是通过配置文件,声明式的创建Spring容器.因此在Web应用中创建Spring容器有如下两种方式: 1. 直接在web.xml文件中配置创建Spring容器. 2. 利用第三方MVC

通过JNDI从服务器容器中获取资源_Spring JNDI+Mysql+Tomcat

通过JNDI从服务器容器中获取DataSource资源 (由容器管理,不要关闭它,容器自己会处理)上一篇我们使用的是dbcp,这里使用JNDI: 使用JNDI连接数据: 在Spring注释 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="userna

Web容器中DefaultServlet详解

Web容器中DefaultServlet详解 https://blog.csdn.net/qq_30920821/article/details/78328608 Web容器中DefaultServlet详解一.什么是defaultServlet 我们以最熟悉的Tomcat服务器为例.我们都知道Jsp和servlet都需要web容器才能运行.但是实际上呢我们的web应用中可以没有任何servlet或者jsp(至少表面上是这样的)只需要一个web.xml,设置在servlet 3.0中,这个也可以

ServletContext读取Web应用中的资源文件

1 package cn.itcast; 2 3 import java.io.FileInputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.PrintWriter; 7 import java.util.Properties; 8 9 import javax.servlet.ServletContext; 10 import javax.servlet.Servlet

Spring 在web 容器中的启动过程

1.对于一个web 应用,其部署在web 容器中,web 容器提供其一个全局的上下文环境,这个上下文就是 ServletContext ,其后面的spring IoC 容器提供宿主环境 2.在web.xml 中会提供有 contextLoaderListener.在web 容器启动时,会触发容器初始化事件,此时 contextLoaderListener 会监听到这个事件,其 contextInitialized 方法会被调用,在这个方法中,spring 会初始化一个启动上下文,这个上下文就被称

IOC容器在web容器中初始化——(一)两种配置方式

参考文章http://blog.csdn.net/liuganggao/article/details/44083817,http://blog.csdn.net/u013185616/article/details/52186184. 最近在研究IOC容器在web容器中初始化的过程.阅读了源码,参照了很多文章,在这里记录一下. 使用的web容器为tomcat7.spring的jar包为4.3.7.RELEASE版本. 我们可以通过web.xml配置文件web容器中声明spring容器.有以下两

【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OSS(https://www.aliyun.com/product/oss) 4.HTTPS(http://baike.baidu.com/view/14121.htm) 阅读目录结构 引: 一.准备工作 二.整体功能结构 三.具体实现步骤 四.关键点和问题处理 五.延伸与扩展 六.总结与思考 引:

tomcat web容器中,调用jersey client端报错的处理

在web工程中,写main方法,运行ok. 发布到tomcat中后,报错. javax.ws.rs.core.UriBuilder.uri(Ljava/lang/String;)Ljavax/ws/rs/core/UriBuilder Caused by:java.lang.AbstractMethodError: javax.ws.rs.core.UriBuilder.uri(Ljava/lang/String;)Ljavax/ws/rs/core/UriBuilder; at javax.w