- 浏览: 733 次
- 性别:
- 来自: 长沙
文章分类
最新评论
JNDI ENC与依赖注入
JNDI ENC与依赖注入
请搞清楚:通过注解还是XML注册资源,通过注入还查找得到资源,注解与XML等价方式。
以下说的是EJB引用资源
每个部署于应用服务器中的EJB容器都拥有一个属于它自己的内部注册表(internal registry),该内部注册表被称为Enterprise Naming Context(ENC),ENC是由JNDI实现的。开发人员可以通过注解或XML为某个EJB 的JNDI ENC(这是一个局部JNDI)定义资源、EJB或外部环境的别名,而后在编写EJB业务逻辑时,通过别名在JNDI中查找这些引用,在EJB3.0中,还可以把这些引用直接注入到bean数据成员中。
JNDI ENC中可以注册哪些内容
指向EJB接口的引用、JMS队列或主题的目标地址、JMS连接工厂、数据源、任何JCA资源、基本的数据类型常量,还有一些java EE服务(javax.ejb.TimerService、javax.transaction.UserTransaction、org.omg.CORBA.ORB)
如何配置JNDI ENC
ENC的JNDI名字空间可以通过XML或通过注解来定义。
如何从ENC中获取引用
通过InitialContext查找
@Stateful
@EJB(name=”ejb/ProcessPayment”, //类级的注解
beanInterface=ProcessPaymentLocal.class,
beanName=”ProcessPaymentBean”)
public class TravelAgentBean implements TravelAgentRemote{
public TicketDO bookPassage(CreditCarDO card,double amount){
ProcessPaymentLocal payment=null;
try{
//EJB厂商不同,初始化方式也许不同
javax.naming.InitialContext ctx=new InitialContext();
//如果是本地接口,对于其他资源(如EntityManagerFactory等)也是类似的查找方法
payment=(ProcessPaymentLocal)ctx.lookup(
“java:comp/env/ejb/ ProcessPayment”);//使用java:comp/env上下文
//如果是远程接口,要用narrow方法
Object ref= ctx.lookup(“java:comp/env/ejb/ ProcessPayment”);
(ProcessPaymentRemote)javax.rmi.PortableRemoteObject.narrow(ref,
ProcessPaymentRemote.class);
}catch(javax.naming.NamingException ne){…..}……..
}
}
使用EJBContext查找
javax.ejb.SessionContext和javax.ejb.MessageDrivenContext接口都继承自javax.ejb.EJBContext,并且都可以用来查找ENC注册项。
@Stateful
@EJB(name=”ejb/ProcessPayment”,
beanInterface=ProcessPaymentLocal.class,
beanName=”ProcessPaymentBean”)
public class TravelAgentBean implements TravelAgentRemote{
@Resource private javax.ejb.SessionContext ejbContext;
public TicketDO bookPassage(CreditCarDO card,double amount){
ProcessPaymentLocal payment=(ProcessPaymentLocal)ejbContext.lookup(
“ejb/ ProcessPayment”);
……….
}
}
注解注入
import com.titan.travelagent;//包名
@Stateful
public class TravelAgentBean implements TravelAgentRemote{
@EJB private ProcessPaymentLocal payment;//通过成员变量注解直接注入
//默认ENC名称为:com.titan.travelagent.TravelAgentBean/payment;
//或者通过setter方法注解直接注入
@EJB public void setProcessPayment(ProcessPaymentLocal payment){
//默认ENC名称为:com.titan.travelagent.TravelAgentBean/processPayment;
this.payment=payment;
}
}
XML注入
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<ejb-local-ref>
<ejb-ref-name> com.titan.travelagent.TravelAgentBean/payment </ejb-ref-name>注册名
<ejb-ref-type>Session</ejb-ref-type>EJB类型有Session、Entity
<local>com.tian.Processpayment.ProcessPaymentLocal</local>
实现接口的EJB,由于ENC名与注解的一致,这个配置会覆盖注解
<ejb-link>ProcessPaymentBean</ejb-link>
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
下面的payment也可以使用processPayment,以通过setter注入
<injection-target-name>payment</injection-target-name>
</injection-target>
</ejb-local-ref>
</session>
</enterprise-beans>
XML覆盖
XML可以覆盖注解,它比注解具有一更高的优先级。覆盖方式见上一节,通过XML可以覆盖注解中要引入的实现类。
注入与继承
如果父类的数据成员或成员方法标有注入用注解,则注入父类的引用也会在子类中被引入,子类也可以覆盖父类的注入注解,但是如果父类的方法是private的,那么子类是无法覆盖它的注入注解的,这时父类和子类可能存在两个不同的引用。
不同类型的引用与注入
EJB类型的引用
@java.ejb.EJB用于引入一个EJB,@java.ejb.EJBs用于引入多个EJB
@EJB(name=”ejb/ProcessPayment”, //ENC注册名
beanInterface=ProcessPaymentLocal.class,//接口
beanName=”processPaymentEJB”,//实现这个接口的类,如果有多个类实现这个接口,必须指定这个
mappedName=”….”)//根据EJB容器厂商的不同而有所不同,可能是一个键值,指向厂商的全局注册表
以上注解标注在bean class类之上,表示注册一个引用,要通过lookup查找,如果用于bean class的setter方法或数据成员(类型是EJB的成员),却表示直接注入
通过XML指定远程EJB引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>//EJB名
<ejb-ref>
<ejb-ref-name> com.titan.travelagent.TravelAgentBean/payment </ejb-ref-name>注册名
<ejb-ref-type>Session</ejb-ref-type> EJB类型有Session、Entity
<remote>com.tian.Processpayment.ProcessPaymentRemote</ remote> 远程接口
<ejb-link>ProcessPaymentBean</ejb-link>实现接口的EJB,如果接口有多个实现类必须配置
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>payment</injection-target-name>也可以使用processPayment
</injection-target>
</ejb-local-ref>
</session>
</enterprise-beans>
通过XML指定本地EJB引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<ejb-local-ref>
<ejb-ref-name> com.titan.travelagent.TravelAgentBean/payment</ejb-ref-name>注册名
<ejb-ref-type>Session</ejb-ref-type> EJB类型有Session、Entity
<local>com.tian.Processpayment.ProcessPaymentLocal</local> 本地接口
<ejb-link>ProcessPaymentBean</ejb-link> 与注解beanName等价,表示引用的EJB名。
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>payment</injection-target-name>也可以使用processPayment
</injection-target>
</ejb-local-ref>
</session>
</enterprise-beans>
EJB名称的二义性和重载
对于某个特定的EJB JAR部署包而言,部署描述文件中的<ejb-name>元素及任何@Stateless或@Stateful注解的name属性必须是全局唯一的。但是对于同一个.ear文件的不同EJB-JAR部署包内,EJB名称是可以重复的,这了区分这些EJB,可以使用扩展语法:@EJB(beanName=”inventory-ejb.jar#InventoryEJB”) InventoryLocal inventory;
EntityManagerFactory类型的引用
在应用服务器对ENC进行配置或将EntityManagerFactory注入到EJB中之后,应用服务器会为你管理EntityManagerFactory实例的生命周期。定义引用的方式:
@javax.persistence.PersistenceUnit(name=”persistence/TitanDB”,//JNDI ENC名
unitName=”TitanDB”)//persistence.xml文件中声明的persistence unit名称
该注解标注bean class时,表示不直接注入,如果标注在bean class的setter方法或数据成员上,表示直接注入,如:
@ PersistenceUnit(unitName=”crmDB”)private EntityManagerFactory crm;
如果要引用多个persistenceunit,要使用@PersistenceUnits注解。
通过XML指定EntityManagerFactory类型的引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<persistence-unit-ref>
< persistence-unit-ref-name>persistence/TitanDB</persistence-unit-ref-name>注册名
persistence.xml文件声明的persistence unit名
< persistence-unit-ame>TitanDB</ persistence-unit-ame>
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>ships<injection-target-name>
</injection-target>
</ persistence-unit-ref >
</session>
</enterprise-beans>
Persistence Unit名称的作用域及重载问题
可以在不同的地方声明persistence unit,它可以定义在EJB-JAR、EAR/lib目录下的JAR或WAR文件中。如果定义的persistence unit有重名,可以通过这个扩展语法访问:@ PersistenceUnit(unitName=”inventory.jar#InventoryDB”)
EntityManager类型的引用
当将EntityManager注册到JNDI ENC或注入到EJB时,EJB容器会对EntityManager所依赖的persistence contect具有完全的控制权(控制它的生命周期),注册方式与EntityManagerFactory很相似,如:
@PersistenceContext(name”persistence/TitanDB”//JNDI ENC名
unitName=”TitanDB”//与peristence.xml文件中声明的peristence unit名称相同
type=PersistenceContextType.EXTENDED)//表示extended persistence context(方法间事务,只用于 //stateful session),还有一个取值TRANSACTION。
可以用于标注bean class,当标注在bean class的setter方法或数据成员上时,表示直接注入,如:
@ PersistenceContext(unitName=”crmDB”)private EntityManager crm;
通过XML指定EntityManager类型的引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<persistence-context-ref>
<persistence-context-ref-name>persistence/TitanDB</persistence-context-ref-name>名
persistence.xml文件声明的persistence unit名
<persistence-context-ame>TitanDB </persistence-context-ame>
<persistence-context-type>EXTENDED</persistence-context-type>
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>ships<injection-target-name>
</injection-target>
</ persistence- context -ref >
</session>
</enterprise-beans>
资源类型的引用
外部资源同样会被映射到JNDI ENC名字空间中的名称上,并且可以有选择地注入到bean实例的数据成员或setter方法中,被引用的外部资源类型可以是:javax.sql.DataSource、javax.jms.ConnectionFactory、javax.jms.QueueConnectionFactory、javax.jms.TopicConnectonFactory、javax.mail.Session、java.net.URL、javax.resource.cci.ConnectionFactory以及由JCA资源适配器定义的其他类型。下面以javax.sql.DataSource为例。
@javax.annotation.Resource(annotation:注解)
@ Resource注解除了用来引用外部资源,还可以用来引用JMS消息的目标地址、JNDI的环境注册项、EJBContext,以及其他Java EE的核心服务。
@ Resource(name=”jdbc/OracleDB”,//JNDI ENC名
type=javax.sql.DataSource,//引入的类别
authenticationType=AuthenticationType.APPLICATION,
//认证方式,有容器认证(取值CONTAINER,容器根据部署的用户名和密码进行认证)和程序自行认证
//(getConnection时要提供用户名和密码)
shareable=true,//多个EJB在同一事务中是否可以使用相同的资源,使用相同的资源连接,以提高性能
mappedName=”java:/DefaultDS”)//外部资源的厂商专用标识符,大多数情况,它的取值等价于一个 //全局JNDI名。
如果要引用多个资源,可以使用@javax.annotation.Resources注解
通过XML指定资源类型的引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<resource-ref>
<res-ref-name>jdbc/OracleDB</res-ref-name>ENC注册名
<res-type>javax.sql.DataSource</res-type>类名
<res-auth>Container</res-auth>
<mapped-name>java:/DefaultDS</mapped-name>
java:/DefaultDS是一个全局JNDI中定义的一个数据源,数据源的配置请查询相关书籍
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>oracle<injection-target-name>
</injection-target>
</resource-ref >
</session>
</enterprise-beans>
资源环境和受管对象
资源环境注册项可以引用包含受管对象的资源,受管对象是一种在部署期间被配置到容器中,并在运行期间由容器负责管理的资源,它的配置书中没有给出例子。资源环境注册项也可可以用于诸如:javax.transaction.Usertransaction和javax.transaction.TransactionSynchronizationRegistry服务,这时定义authenticationType和shareable 是非法的。
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<resource-env-ref>
<resource-env-ref-name>jdbc/OracleDB</resource-env-ref-name>//ENC注册名
<resource-env-ref-type>javax.transaction.Usertransaction</resource-env-ref-type>类
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>utx<injection-target-name>
</injection-target>
</resource-env-ref >
</session>
</enterprise-beans>
环境注册项还可以用来配置String、Integer、Long、Double、Float、Byte、Boolean和Short这些包装类型的常量。
<enterprise-beans>
<session>
<ejb-name>ProcessPaymentBean</ejb-name>
<env-entry>
<env-entry-name>minCheckNumber</env-entry-name>ENC注册名
<env-entry-type>java.lang.Integer</env-entry-type>类名
<env-entry-value>2000</env-entry-value>常量值,这种引用几乎都是用XML来配置的
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.processpayment.ProcessPaymentBean
</injection-target-class>
<injection-target-name>minCheckNumber<injection-target-name>
</injection-target>
</env-entry>
</session>
</enterprise-beans>
消息目标地址类型的引用
在JNDI ENC中注册的消息目标地址引用指向JMS的主题或队列。
@Resource(name=”jms/TicketTopic”,//ENC名
type=javax.jms.Topic,//类型,还可以是队列(javax.jms.Queue)
mappedName=”topic/TicketTopic”)//全局的厂商专用标识符
注意,使用注解无法设置目标地址的连接(message-destincton-link)
等价XML
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<message-destination-ref>
<message-destination-ref-name>jms/TicketTopic</message-destination-ref-name>注册名
<message-destination-type>javax.jms.Topic</message-destination-type>消息类型
从目标地址收消息还是向其发消息
<message-destination-usage>Produces</message-destination-usage>
<message-destination-link>Distributor </message-destination-link>消息分发地址
<mapped-name> topic/TicketTopic </mapped-name>
topic/TicketTopic表示主题,它的配置请找相关书籍,原书练习中只讲到配置队列
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>ticketTopic <injection-target-name>
</injection-target>
</ message-destination-ref >
</session>
</enterprise-beans>
Web Service类型的引用
在JNDI ENC中注册的web service引用指向服务的接口或服务的终端接口。19章有详细介绍
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<service-ref>
<service-ref-name>service/ChargeItProcessorService</service-ref-name>ENC注册名
<service-interface>com.charge_it.ProcessorService</service-interface>JAX-RPC服务接口
<wsdl-file>META-INF/wsdl/ChargeItProcesor.wsdl</wsdl-file> WSDL文件位置
<jaxrpc-mapping-file>META-INF/mapping.xml </jaxrpc-mapping-file> JAX-RPC映射文件
<service-qname>chargeIt:ProcessorService</service-qname>与WSDL文件定义的服务名一致
<mapped-name>webservice/ChargeItProcessorService</mapped-name>
webservice/ChargeItProcessorService映射应用服务器全局注册项
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>chargeService <injection-target-name>
</injection-target>
</ message-destination-ref >
</session>
</enterprise-beans>
请搞清楚:通过注解还是XML注册资源,通过注入还查找得到资源,注解与XML等价方式。
以下说的是EJB引用资源
每个部署于应用服务器中的EJB容器都拥有一个属于它自己的内部注册表(internal registry),该内部注册表被称为Enterprise Naming Context(ENC),ENC是由JNDI实现的。开发人员可以通过注解或XML为某个EJB 的JNDI ENC(这是一个局部JNDI)定义资源、EJB或外部环境的别名,而后在编写EJB业务逻辑时,通过别名在JNDI中查找这些引用,在EJB3.0中,还可以把这些引用直接注入到bean数据成员中。
JNDI ENC中可以注册哪些内容
指向EJB接口的引用、JMS队列或主题的目标地址、JMS连接工厂、数据源、任何JCA资源、基本的数据类型常量,还有一些java EE服务(javax.ejb.TimerService、javax.transaction.UserTransaction、org.omg.CORBA.ORB)
如何配置JNDI ENC
ENC的JNDI名字空间可以通过XML或通过注解来定义。
如何从ENC中获取引用
通过InitialContext查找
@Stateful
@EJB(name=”ejb/ProcessPayment”, //类级的注解
beanInterface=ProcessPaymentLocal.class,
beanName=”ProcessPaymentBean”)
public class TravelAgentBean implements TravelAgentRemote{
public TicketDO bookPassage(CreditCarDO card,double amount){
ProcessPaymentLocal payment=null;
try{
//EJB厂商不同,初始化方式也许不同
javax.naming.InitialContext ctx=new InitialContext();
//如果是本地接口,对于其他资源(如EntityManagerFactory等)也是类似的查找方法
payment=(ProcessPaymentLocal)ctx.lookup(
“java:comp/env/ejb/ ProcessPayment”);//使用java:comp/env上下文
//如果是远程接口,要用narrow方法
Object ref= ctx.lookup(“java:comp/env/ejb/ ProcessPayment”);
(ProcessPaymentRemote)javax.rmi.PortableRemoteObject.narrow(ref,
ProcessPaymentRemote.class);
}catch(javax.naming.NamingException ne){…..}……..
}
}
使用EJBContext查找
javax.ejb.SessionContext和javax.ejb.MessageDrivenContext接口都继承自javax.ejb.EJBContext,并且都可以用来查找ENC注册项。
@Stateful
@EJB(name=”ejb/ProcessPayment”,
beanInterface=ProcessPaymentLocal.class,
beanName=”ProcessPaymentBean”)
public class TravelAgentBean implements TravelAgentRemote{
@Resource private javax.ejb.SessionContext ejbContext;
public TicketDO bookPassage(CreditCarDO card,double amount){
ProcessPaymentLocal payment=(ProcessPaymentLocal)ejbContext.lookup(
“ejb/ ProcessPayment”);
……….
}
}
注解注入
import com.titan.travelagent;//包名
@Stateful
public class TravelAgentBean implements TravelAgentRemote{
@EJB private ProcessPaymentLocal payment;//通过成员变量注解直接注入
//默认ENC名称为:com.titan.travelagent.TravelAgentBean/payment;
//或者通过setter方法注解直接注入
@EJB public void setProcessPayment(ProcessPaymentLocal payment){
//默认ENC名称为:com.titan.travelagent.TravelAgentBean/processPayment;
this.payment=payment;
}
}
XML注入
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<ejb-local-ref>
<ejb-ref-name> com.titan.travelagent.TravelAgentBean/payment </ejb-ref-name>注册名
<ejb-ref-type>Session</ejb-ref-type>EJB类型有Session、Entity
<local>com.tian.Processpayment.ProcessPaymentLocal</local>
实现接口的EJB,由于ENC名与注解的一致,这个配置会覆盖注解
<ejb-link>ProcessPaymentBean</ejb-link>
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
下面的payment也可以使用processPayment,以通过setter注入
<injection-target-name>payment</injection-target-name>
</injection-target>
</ejb-local-ref>
</session>
</enterprise-beans>
XML覆盖
XML可以覆盖注解,它比注解具有一更高的优先级。覆盖方式见上一节,通过XML可以覆盖注解中要引入的实现类。
注入与继承
如果父类的数据成员或成员方法标有注入用注解,则注入父类的引用也会在子类中被引入,子类也可以覆盖父类的注入注解,但是如果父类的方法是private的,那么子类是无法覆盖它的注入注解的,这时父类和子类可能存在两个不同的引用。
不同类型的引用与注入
EJB类型的引用
@java.ejb.EJB用于引入一个EJB,@java.ejb.EJBs用于引入多个EJB
@EJB(name=”ejb/ProcessPayment”, //ENC注册名
beanInterface=ProcessPaymentLocal.class,//接口
beanName=”processPaymentEJB”,//实现这个接口的类,如果有多个类实现这个接口,必须指定这个
mappedName=”….”)//根据EJB容器厂商的不同而有所不同,可能是一个键值,指向厂商的全局注册表
以上注解标注在bean class类之上,表示注册一个引用,要通过lookup查找,如果用于bean class的setter方法或数据成员(类型是EJB的成员),却表示直接注入
通过XML指定远程EJB引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>//EJB名
<ejb-ref>
<ejb-ref-name> com.titan.travelagent.TravelAgentBean/payment </ejb-ref-name>注册名
<ejb-ref-type>Session</ejb-ref-type> EJB类型有Session、Entity
<remote>com.tian.Processpayment.ProcessPaymentRemote</ remote> 远程接口
<ejb-link>ProcessPaymentBean</ejb-link>实现接口的EJB,如果接口有多个实现类必须配置
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>payment</injection-target-name>也可以使用processPayment
</injection-target>
</ejb-local-ref>
</session>
</enterprise-beans>
通过XML指定本地EJB引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<ejb-local-ref>
<ejb-ref-name> com.titan.travelagent.TravelAgentBean/payment</ejb-ref-name>注册名
<ejb-ref-type>Session</ejb-ref-type> EJB类型有Session、Entity
<local>com.tian.Processpayment.ProcessPaymentLocal</local> 本地接口
<ejb-link>ProcessPaymentBean</ejb-link> 与注解beanName等价,表示引用的EJB名。
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>payment</injection-target-name>也可以使用processPayment
</injection-target>
</ejb-local-ref>
</session>
</enterprise-beans>
EJB名称的二义性和重载
对于某个特定的EJB JAR部署包而言,部署描述文件中的<ejb-name>元素及任何@Stateless或@Stateful注解的name属性必须是全局唯一的。但是对于同一个.ear文件的不同EJB-JAR部署包内,EJB名称是可以重复的,这了区分这些EJB,可以使用扩展语法:@EJB(beanName=”inventory-ejb.jar#InventoryEJB”) InventoryLocal inventory;
EntityManagerFactory类型的引用
在应用服务器对ENC进行配置或将EntityManagerFactory注入到EJB中之后,应用服务器会为你管理EntityManagerFactory实例的生命周期。定义引用的方式:
@javax.persistence.PersistenceUnit(name=”persistence/TitanDB”,//JNDI ENC名
unitName=”TitanDB”)//persistence.xml文件中声明的persistence unit名称
该注解标注bean class时,表示不直接注入,如果标注在bean class的setter方法或数据成员上,表示直接注入,如:
@ PersistenceUnit(unitName=”crmDB”)private EntityManagerFactory crm;
如果要引用多个persistenceunit,要使用@PersistenceUnits注解。
通过XML指定EntityManagerFactory类型的引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<persistence-unit-ref>
< persistence-unit-ref-name>persistence/TitanDB</persistence-unit-ref-name>注册名
persistence.xml文件声明的persistence unit名
< persistence-unit-ame>TitanDB</ persistence-unit-ame>
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>ships<injection-target-name>
</injection-target>
</ persistence-unit-ref >
</session>
</enterprise-beans>
Persistence Unit名称的作用域及重载问题
可以在不同的地方声明persistence unit,它可以定义在EJB-JAR、EAR/lib目录下的JAR或WAR文件中。如果定义的persistence unit有重名,可以通过这个扩展语法访问:@ PersistenceUnit(unitName=”inventory.jar#InventoryDB”)
EntityManager类型的引用
当将EntityManager注册到JNDI ENC或注入到EJB时,EJB容器会对EntityManager所依赖的persistence contect具有完全的控制权(控制它的生命周期),注册方式与EntityManagerFactory很相似,如:
@PersistenceContext(name”persistence/TitanDB”//JNDI ENC名
unitName=”TitanDB”//与peristence.xml文件中声明的peristence unit名称相同
type=PersistenceContextType.EXTENDED)//表示extended persistence context(方法间事务,只用于 //stateful session),还有一个取值TRANSACTION。
可以用于标注bean class,当标注在bean class的setter方法或数据成员上时,表示直接注入,如:
@ PersistenceContext(unitName=”crmDB”)private EntityManager crm;
通过XML指定EntityManager类型的引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<persistence-context-ref>
<persistence-context-ref-name>persistence/TitanDB</persistence-context-ref-name>名
persistence.xml文件声明的persistence unit名
<persistence-context-ame>TitanDB </persistence-context-ame>
<persistence-context-type>EXTENDED</persistence-context-type>
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>ships<injection-target-name>
</injection-target>
</ persistence- context -ref >
</session>
</enterprise-beans>
资源类型的引用
外部资源同样会被映射到JNDI ENC名字空间中的名称上,并且可以有选择地注入到bean实例的数据成员或setter方法中,被引用的外部资源类型可以是:javax.sql.DataSource、javax.jms.ConnectionFactory、javax.jms.QueueConnectionFactory、javax.jms.TopicConnectonFactory、javax.mail.Session、java.net.URL、javax.resource.cci.ConnectionFactory以及由JCA资源适配器定义的其他类型。下面以javax.sql.DataSource为例。
@javax.annotation.Resource(annotation:注解)
@ Resource注解除了用来引用外部资源,还可以用来引用JMS消息的目标地址、JNDI的环境注册项、EJBContext,以及其他Java EE的核心服务。
@ Resource(name=”jdbc/OracleDB”,//JNDI ENC名
type=javax.sql.DataSource,//引入的类别
authenticationType=AuthenticationType.APPLICATION,
//认证方式,有容器认证(取值CONTAINER,容器根据部署的用户名和密码进行认证)和程序自行认证
//(getConnection时要提供用户名和密码)
shareable=true,//多个EJB在同一事务中是否可以使用相同的资源,使用相同的资源连接,以提高性能
mappedName=”java:/DefaultDS”)//外部资源的厂商专用标识符,大多数情况,它的取值等价于一个 //全局JNDI名。
如果要引用多个资源,可以使用@javax.annotation.Resources注解
通过XML指定资源类型的引用
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<resource-ref>
<res-ref-name>jdbc/OracleDB</res-ref-name>ENC注册名
<res-type>javax.sql.DataSource</res-type>类名
<res-auth>Container</res-auth>
<mapped-name>java:/DefaultDS</mapped-name>
java:/DefaultDS是一个全局JNDI中定义的一个数据源,数据源的配置请查询相关书籍
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>oracle<injection-target-name>
</injection-target>
</resource-ref >
</session>
</enterprise-beans>
资源环境和受管对象
资源环境注册项可以引用包含受管对象的资源,受管对象是一种在部署期间被配置到容器中,并在运行期间由容器负责管理的资源,它的配置书中没有给出例子。资源环境注册项也可可以用于诸如:javax.transaction.Usertransaction和javax.transaction.TransactionSynchronizationRegistry服务,这时定义authenticationType和shareable 是非法的。
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<resource-env-ref>
<resource-env-ref-name>jdbc/OracleDB</resource-env-ref-name>//ENC注册名
<resource-env-ref-type>javax.transaction.Usertransaction</resource-env-ref-type>类
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>utx<injection-target-name>
</injection-target>
</resource-env-ref >
</session>
</enterprise-beans>
环境注册项还可以用来配置String、Integer、Long、Double、Float、Byte、Boolean和Short这些包装类型的常量。
<enterprise-beans>
<session>
<ejb-name>ProcessPaymentBean</ejb-name>
<env-entry>
<env-entry-name>minCheckNumber</env-entry-name>ENC注册名
<env-entry-type>java.lang.Integer</env-entry-type>类名
<env-entry-value>2000</env-entry-value>常量值,这种引用几乎都是用XML来配置的
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.processpayment.ProcessPaymentBean
</injection-target-class>
<injection-target-name>minCheckNumber<injection-target-name>
</injection-target>
</env-entry>
</session>
</enterprise-beans>
消息目标地址类型的引用
在JNDI ENC中注册的消息目标地址引用指向JMS的主题或队列。
@Resource(name=”jms/TicketTopic”,//ENC名
type=javax.jms.Topic,//类型,还可以是队列(javax.jms.Queue)
mappedName=”topic/TicketTopic”)//全局的厂商专用标识符
注意,使用注解无法设置目标地址的连接(message-destincton-link)
等价XML
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<message-destination-ref>
<message-destination-ref-name>jms/TicketTopic</message-destination-ref-name>注册名
<message-destination-type>javax.jms.Topic</message-destination-type>消息类型
从目标地址收消息还是向其发消息
<message-destination-usage>Produces</message-destination-usage>
<message-destination-link>Distributor </message-destination-link>消息分发地址
<mapped-name> topic/TicketTopic </mapped-name>
topic/TicketTopic表示主题,它的配置请找相关书籍,原书练习中只讲到配置队列
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>ticketTopic <injection-target-name>
</injection-target>
</ message-destination-ref >
</session>
</enterprise-beans>
Web Service类型的引用
在JNDI ENC中注册的web service引用指向服务的接口或服务的终端接口。19章有详细介绍
<enterprise-beans>
<session>
<ejb-name>TravelAgentBean</ejb-name>
<service-ref>
<service-ref-name>service/ChargeItProcessorService</service-ref-name>ENC注册名
<service-interface>com.charge_it.ProcessorService</service-interface>JAX-RPC服务接口
<wsdl-file>META-INF/wsdl/ChargeItProcesor.wsdl</wsdl-file> WSDL文件位置
<jaxrpc-mapping-file>META-INF/mapping.xml </jaxrpc-mapping-file> JAX-RPC映射文件
<service-qname>chargeIt:ProcessorService</service-qname>与WSDL文件定义的服务名一致
<mapped-name>webservice/ChargeItProcessorService</mapped-name>
webservice/ChargeItProcessorService映射应用服务器全局注册项
<injection-target> 要直接注入时才用这个配置
<injection-target-class>
com.titan.travelagent.TravelAgentBean
</injection-target-class>
<injection-target-name>chargeService <injection-target-name>
</injection-target>
</ message-destination-ref >
</session>
</enterprise-beans>
相关推荐
在深入探讨JNDI注入与Java反序列化漏洞之前,我们需要对几个关键概念有所了解,这包括Java远程方法调用(RMI)、Java名称目录接口(JNDI)、Java远程消息交换协议(JRMP)、以及序列化和反序列化。 RMI是Java环境中...
Spring 三种依赖注入方式 Spring 框架中提供了多种依赖注入方式,其中最常用的三种依赖注入方式分别是接口注入、设值注入和构造函数注入。下面,我们将分别对这三种依赖注入方式进行详细的介绍和分析。 一、接口...
1. `fscontext.jar`:这是一个提供文件系统上下文(FileSystemContext)的JAR文件,它使得JNDI能够与本地文件系统进行交互。通过这个库,开发者可以使用JNDI接口来查找和操作文件系统中的资源,就像处理远程对象一样...
JNDI注入利用工具 介绍 本项目为JNDI注入利用工具,生成JNDI连接并启动初始化相关服务,可用于Fastjson,Jackson等相关突破的验证。 本项目是基于welk1n的 ,在此项目的基础服务框架上,重新编写了攻击利用代码,...
依赖注入(Dependency Injection,简称DI)是Java编程中一种重要的设计模式,特别是在企业级Java应用(Enterprise JavaBeans,EJB)3.0版本中得到了广泛的应用。依赖注入的核心思想是解耦,它允许开发者在不修改代码...
**JNDI注入详解** Java Naming and Directory Interface (JNDI) 是Java应用程序用来查找和管理网络资源的接口。它不依赖于特定的目录服务,而是通过服务提供者接口(SPI)来支持多种不同的目录服务,如LDAP、DNS等...
6. lib 文件夹可能包含了依赖的库文件,这些库可能与其他服务或组件的集成有关。 总的来说,这个JNDI-1.2.1开源包为Java开发者提供了访问和管理命名服务的能力,通过其API可以实现查找和绑定对象,进行目录服务操作...
总结来说,"jndi-tool"是一个强大的JNDI服务利用工具,适用于评估和利用与Fastjson和Log4j漏洞相关的RCE风险。它利用RMI和LDAP协议,可以在高版本JDK环境下运行,为安全专业人士提供了一种有效测试环境安全性的手段...
Spring 依赖注入知识点分享 在本篇文章中,我们将详细介绍 Spring 依赖注入的知识点,并提供相关的代码内容。 什么是 IoC IoC(Inversion of Control),即控制反转,是一种软件设计模式。它将对象之间的依赖关系...
《深入解析JNDI注入攻击与防御》 Java Naming and Directory Interface (JNDI) 是Java平台中用于访问各种命名和目录服务的API,它提供了一种统一的方式来查找和访问不同类型的网络资源,如数据库、对象、服务器等。...
8. **JNDI与EJB和JDBC**:在Enterprise JavaBeans (EJB) 中,JNDI用于查找和注入EJB实例。在Java Database Connectivity (JDBC) 中,数据源通常通过JNDI查找来获取,这样可以轻松地在不同环境中配置数据库连接。 9....
一款用于 JNDI注入利用的工具,大量参考/引用了Rogue JNDI项目的代码,支持直接植入内存shell,并集成了常见的bypass 高版本JDK的方式,适用于与自动化工具配合使用。 使用 java -jar JNDIExploit.jar -h 查看参数...
用于JNDI注入攻击的恶意LDAP服务器。 描述 该项目包含LDAP和HTTP服务器,用于利用默认情况下不安全的Java JNDI API。 为了执行攻击,您可以在本地启动这些服务器,然后在易受攻击的客户端上触发JNDI解析,例如: ...
绑定是将一个名字与一个对象关联的过程,通过这个名字,我们可以获取到对应的对象。 JNDI操作主要包括以下步骤: 1. 创建初始上下文(Initial Context):这是访问JNDI服务的第一步,通常使用`InitialContext()`...
在整合JNDI时,可能需要在Struts配置文件(struts-config.xml或struts2的struts.xml)中注入依赖的服务或数据源。 2. **Spring:** Spring作为IoC/DI容器负责组件的管理和装配。可以利用Spring的JNDI_lookup标签...
描述中的内容与标题相同,没有提供额外的信息,但我们可以推测这可能是一个研究、教育或安全审计用途的工具包,用于理解和防范JNDI注入攻击。 标签"java 网络安全"进一步确认了这个主题是关于Java编程语言在网络...
#### 二、JNDI与Tomcat ##### 2.1 JNDI概述 JNDI提供了一种查找和定位应用程序所用资源的标准化方式,这些资源包括数据库连接、消息队列、EJBs、对象引用等。JNDI的核心概念包括: - **命名**:使用名字来标识...
减少耦合的方法包括使用接口、依赖注入、模块化设计等。 综合来看,"jndi 反射 耦合"这三个概念在实际开发中都扮演着关键角色。理解并合理运用JNDI可以提高程序的灵活性,掌握反射能够实现动态编程,而降低耦合性则...
`jndi-1.2.1.jar` 是包含JNDI 1.2.1实现的库文件,它是Java应用程序使用JNDI功能的必要依赖。开发者在项目中引入这个库,即可利用JNDI 1.2.1提供的强大功能,实现命名和目录服务的灵活接入。 总结来说,JNDI 1.2.1...