Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 The JNDI ENC and Injection Every EJB container that is deployed in an application server has its own personal internal registry called the Enterprise.

Similar presentations


Presentation on theme: "1 The JNDI ENC and Injection Every EJB container that is deployed in an application server has its own personal internal registry called the Enterprise."— Presentation transcript:

1 1 The JNDI ENC and Injection Every EJB container that is deployed in an application server has its own personal internal registry called the Enterprise Naming Context (ENC). This ENC is implemented by JNDI and is a sandbox where the EJB container can hold specific references to its environment. Think of it as the EJB container's personal address book, where it writes down addresses to various Java EE services that it wants to look up and use within its business logic.

2 2 The JNDI ENC The ENC has been around in the EJB specification since the early 1.0 days. It began as a local JNDI namespace that was specific to an EJB container. Developers could define aliases to resources, EJBs, and environment entries in the JNDI ENC through EJB XML deployment descriptors. These aliases could then be looked up directly in JNDI within business logic. In EJB 3.0, this mechanism was enhanced so that JNDI ENC references could be injected directly into the fields of a bean class. Annotations are the primary mechanism for doing this, but XML deployment descriptor support is available for those who wish to use that abstraction.

3 3 What Can Be Registered in the JNDI ENC? Many different items can be bound to the ENC: references to any EJB interface, a JMS queue or topic destination, JMS connection factories, data sources, any JCA resource, and even primitive values. Java EE services such as javax.transaction.UserTransaction, javax.ejb.TimerService, and org.omg.CORBA.ORB are also available in the ENC.

4 4 How Is the JNDI ENC Populated? The ENC's JNDI namespace is populated in two separate ways: via XML or via annotations. Any reference that you declare in XML to a service or resource automatically populates the JNDI ENC with the reference's name. Any environment annotation that you use in your bean class also causes the ENC to be populated. Once an item is bound to the JNDI ENC of the EJB container, it can be referenced by a JNDI lookup.

5 5 XML Population To illustrate how XML population works, let's define a reference to the stateless session bean we wrote in Lecture 11. Here we define a local interface reference to the ProcessPayment EJB for the TravelAgent EJB: TravelAgentBean ejb/ProcessPayment Session com.titan.processpayment.ProcessPaymentLocal ProcessPaymentBean

6 6 XML Population The element tells the EJB container that the TravelAgentBean wants a reference to the ProcessPayment EJB. A reference to this bean is registered in the TravelAgentBean's JNDI ENC under the name ejb/ProcessPayment. This is defined by the element. Other referenceable things, like resources and JMS destinations, have similar XML elements such as to specify how and where the reference will be bound into their JNDI ENCs. Each service type in Java EE has its own reference syntax.

7 7 Annotation Population Each referenceable type also has a corresponding annotation that can be used as an alternative to XML. If you specify these annotations on the bean class, they will cause the JNDI ENC to be populated with the information defined in the annotation: import javax.annotation.EJB; @Stateful @EJB(name="ejb/ProcessPayment", beanInterface=ProcessPaymentLocal.class, beanName="ProcessPaymentBean") public class TravelAgentBean implements TravelAgentRemote {... }

8 8 Annotation Population In this example, we are registering a reference to the ProcessPayment EJB under the ejb/ProcessPayment name. Business logic running inside the TravelAgentBean is able to do JNDI lookups to find this reference. Each environment annotation, such as @javax.annotation.EJB, has a name( ) attribute that specifies the JNDI ENC name to which you want the service reference to be bound.

9 9 How Are Things Referenced from the ENC? Anything registered in the JNDI ENC can be looked up by name under the java:comp/env context. The comp part of this name corresponds to component. The JNDI name resolves to a different context depending on where you invoke the lookup. For example, if you invoke jndi.lookup("java:comp/env") within the TravelAgentBean, you will get that EJB container's ENC. If you do the same within ProcessPaymentBean, you will get a different ENC registry specific to that bean. The application server knows what ENC is active when you perform the lookup. @Stateful @EJB(name="ejb/ProcessPayment", beanInterface=ProcessPaymentLocal.class, beanName="ProcessPaymentBean")

10 10 How Are Things Referenced from the ENC? public class TravelAgentBean implements TravelAgentRemote { public TicketDO bookPassage(CreditCardDO card, double amount) { ProcessPaymentLocal payment = null; try { javax.naming.InitialContext ctx = new InitialContext( ); payment = (ProcessPaymentLocal) ctx.lookup("java:comp/env/ejb/ProcessPayment"); } catch (javax.naming.NamingException ne) { throw new EJBException(ne); } payment.process(card, customer, amount);... }

11 11 How Are Things Referenced from the ENC? In this example, the bookPassage( ) method from our TravelAgent EJB needs a reference to the ProcessPayment EJB so that it can bill the customer for the reservation. A reference to the ProcessPayment EJB was created in the TravelAgent's ENC by annotating the bean class with the @EJB annotation. The preceding code does a JNDI lookup to find this reference. While the ProcessPayment.process( ) method is invoked, the java:comp/env/ejb/ProcessPayment reference is no longer available because the ProcessPayment's ENC is active instead of the TravelAgent's ENC.

12 12 Annotation injection Instead of an ENC lookup, the ProcessPayment EJB reference can be injected directly into a member variable of the TravelAgent EJB. This injection can be done through environment annotations or an XML deployment descriptor fragment: @Stateful public class TravelAgentBean implements TravelAgentRemote { @EJB private ProcessPaymentLocal payment;... } By using the @javax.ejb.EJB annotation on the payment field of the TravelAgentBean class, the EJB container will automatically inject a reference to the ProcessPayment EJB directly into the payment field when the TravelAgent bean instance is created.

13 13 Annotation injection Alternatively, if you do not like this form of injection, the specification also supports injecting via a bean setter method: @Stateful public class TravelAgentBean implements TravelAgentRemote { private ProcessPaymentLocal payment; @EJB public void setProcessPayment(ProcessPaymentLocal payment) { this.payment = payment; } Unlike the previous example, when the TravelAgentBean instance is allocated, the EJB container will instead invoke the setProcessPayment( ) method, passing in the EJB reference as a parameter.

14 14 XML injection If you prefer not to use annotations to initialize the fields of your bean class, then the element is available to you in your ejb-jar.xml deployment descriptor: TravelAgentBean ProcessPayment Session com.titan.processpayment.ProcessPaymentLocal ProcessPaymentBean com.titan.travelagent.TravelAgentBean payment

15 15 XML injection Each XML environment element such as can use to populate a field or call a setter method with the referenced item. The element is the class where your field or method is declared. This may seem unnecessarily verbose, but this becomes important when there are inheritance hierarchies.

16 16 Injection and inheritance It is possible for a bean class to be part of a class hierarchy. If any fields or methods have injection annotations on them, they will still be populated, but certain injection rules are followed: public class BaseClass { @Resource DataSource data; @EJB(beanName="ProcessPaymentBean") public void setProcessPayment(ProcessPaymentLocal pp) {... } @Stateless public class MySessionBean extends BaseClass implements MySessionRemote {... }

17 17 Injection and inheritance In this example, we have a stateless session bean class that inherits from a base class. All instances of MySessionBean would have the appropriate resource injected into the base class's data field as well as the setProcessPayment( ) method. It is possible to change what is injected into the setProcessPayment( ) method by reimplementing and overriding it in the subclass: @Stateless public class MySessionBean extends BaseClass implements MySessionRemote { @EJB(beanName="AcmeProcessPayment") public void setProcessPayment(ProcessPaymentLocal pp) {... }... }

18 18 Injection and inheritance The ProcessPaymentBean would no longer be injected into the setProcessPayment( ) method. Instead, the new overridden reference, AcmeProcessPayment, would be injected. There is one exception to this rule. If the setProcessPayment( ) method in the BaseClass was a private method rather than a protected or public method, then the base class would still be injected with the old reference: public class BaseClass { @Resource DataSource data; @EJB(beanName="ProcessPaymentBean") private void setProcessPayment(ProcessPaymentLocal pp) {... }

19 19 Injection and inheritance @Stateless public class MySessionBean extends BaseClass implements MySessionRemote { @EJB(beanName="AcmeProcessPayment") public void setProcessPayment(ProcessPaymentLocal pp) {... }... } So, in the previous example, both setProcessPayment( ) methods would be invoked and set with a different ProcessPaymentLocal reference. The BaseClass 's setProcessPayment( ) method would get a reference to the ProcessPaymentBean, and the setProcessPayment( ) method of MySessionBean would get AcmeProcessPayment.

20 20 @javax.ejb.EJB The @javax.ejb.EJB annotation can be used on your bean class's setter methods, on member fields, or directly on the class itself: package javax.ejb; @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface EJB { String name( ) default ""; Class beanInterface( ) default Object.class; String beanName( ) default ""; String mappedName( ) default ""; }

21 21 XML-based remote EJB references The element defines a reference to remote EJBs. It contains the subelements (optional), (required), (required), (required), (optional), (optional), and (optional), as well as the element (optional) described in the first part of this chapter. Here is a remote reference to the ProcessPayment EJB: TravelAgentBean ejb/ProcessPaymentRemote Session com.titan.processpayment.ProcessPaymentRemote

22 22 XML-based local EJB references The element defines a reference to remote EJBs. It contains the subelements (optional), (required), (required), (required), (optional), (optional), and (optional), as well as the element (optional) described in the first part of this chapter. Here is a local reference to the ProcessPayment EJB: TravelAgentBean ejb/ProcessPaymentRemote Session com.titan.processpayment.ProcessPaymentLocal

23 23 @javax.persistence.PersistenceUnit The @javax.persistence.PersistenceUnit annotation can be used on your bean class's setter methods or member fields, or directly on the class itself: package javax.persistence; @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface PersistenceUnit { String name( ) default ""; String unitName( ) default ""; }

24 24 @javax.persistence.PersistenceContext The @javax.persistence.PersistenceContext annotation can be used on your bean class's setter methods or member fields, or directly on the class itself: package javax.persistence; public enum PersistenceContextType { TRANSACTION, EXTENDED }

25 25 @javax.persistence.PersistenceContext @Target({}) @Retention(RUNTIME) public @interface PersistenceProperty { String name( ); String value( ); } @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface PersistenceContext { String name( ) default ""; String unitName( ) default ""; PersistenceContextType type( ) default TRANSACTION; PersistenceProperty[] properties( ) default {}; }

26 26 @javax.annotation.Resource The @javax.annotation.Resource annotation is used to reference an external resource. It can be applied to your bean class's setter methods or member fields, or directly on the class itself. This annotation is highly overloaded and overused in the Java EE specification in that in addition to external resources, it is also used to reference JMS message destinations, environment entries, EJBContext s, and Java EE core services. For now, we'll focus solely on using this annotation to access external resources:

27 27 @javax.annotation.Resource package javax.annotation; @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface Resource { public enum AuthenticationType { CONTAINER, APPLICATION } String name( ) default ""; Class type( ) default Object.class; AuthenticationType authenticationType( ) default v AuthenticationType.CONTAINER; boolean shareable( ) default true; String description( ) default ""; String mappedName( ) default ""; }

28 28 Shareable resources When several enterprise beans in a transaction use the same resource, you will want to configure your EJB server to share that resource. Sharing a resource means that each EJB will use the same connection to access the resource (e.g., database or JMS provider), a strategy that is more efficient than using separate resource connections. In terms of a database, EJBs that are referencing the same database will probably want to use the same database connection during a transaction so that all CRUD operations return consistent results.

29 29 Shareable resources EJB containers share resources by default, but resource sharing can be turned on or off explicitly with the shareable( ) attribute of the @Resource annotation. Occasionally, advanced developers may run into situations where resource sharing is not desirable, and having the option to turn off resource sharing is beneficial. Unless you have a good reason for turning off resource sharing, we recommend that you set the shareable( ) attribute to true.

30 30 XML-based resource references The element defines a reference to a given resource. It contains the subelements (optional), (required), (required), (required), (optional), and (optional), as well as the element (optional) described in the first section of this chapter. Here is an example of a reference to a data source of TitanDB: TravelAgentBean jdbc/OracleDB javax.sql.DataSource Container java:/DefaultDS

31 31 Environment Entries In Lecture 11, the ProcessPayment EJB had a configurable property for minimum check number. These types of configurable properties are called environment entries. The bean can use environment entries to customize its behavior. Although they can be defined using annotations, environment entries are almost always configured via XML, as they really are configuration values and not metadata. The element is used to define them. This element contains the subelements (optional), (required), (required), and (optional), as well as the element (optional). Here is a typical declaration:

32 32 Environment Entries ProcessPaymentBean minCheckNumber java.lang.Integer 2000


Download ppt "1 The JNDI ENC and Injection Every EJB container that is deployed in an application server has its own personal internal registry called the Enterprise."

Similar presentations


Ads by Google