Web Tier to Go With Java EE 5: A Look at Resource Injection

转载 2006年06月12日 21:53:00
 
By Ryan Lubke, June 2006  

Articles Index

The focus of the Java Platform, Enterprise Edition (Java EE) 5 is ease of development, with the goal of making typical application tasks simpler. An important new feature that helps fulfill this goal is support for annotations. Annotations enable injecting dependencies, resources, services, and life-cycle notifications into a Java EE 5 platform application.

This fourth article of the series describes how the platform's web-tier technologies support injection through Java technology annotations to simplify access to resources, environment data, and life-cycle control.

A Look at Resource Injection

To understand how resource injection makes life easier for developers, let's look at how applications accessed resources prior to support for resource injection and how the Java EE 5 platform has simplified this access. In the past, accessing data sources, web services, environment entries, and EJB software references required the use of boilerplate code. For example, the code required to access the container-managed data source javax.sql.DataSource would look like this:

public javax.sql.DataSource getCatalogDS() {
try {
// Obtain the initial Java Naming and Directory Interface
// (JNDI) context.
InitialContext initCtx = new InitialContext();
// Perform JNDI lookup to obtain the resource.
catalogDS = (DataSource)
initCtx.lookup("java:comp/env/jdbc/catalogDS");
} catch (NamingException ex) {
// Handle failure.
}
}

...

public getProductsByCategory() {
// Get the DataSource.
DataSource catalogDS = getCatalogDS();
// Get a connection and execute the query.
Connection conn = catalogDS.getConnection();
...

}
 

In order to look up a data source, a developer had to deal with the following:

  • Java Naming and Directory Interface (JNDI) API. The application looked up the resource by way of the JNDI API.
  • Casting. The look-up result had to be cast to the correct type.
  • Exception handling. The software had to handle the exceptions exposed by the JNDI API.

Moreover, the developer had to define the resource to acess in the deployment descriptor, web.xml, associated with the web application:

<resource-ref>
<description>Catalog DataSource</description>
<res-ref-name>jdbc/catalogDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
 

The Java EE 5 platform defines annotations to support a variety of injections. We can now reduce the code in the example above to the following:

private @Resource DataSource catalogDS;

public getProductsByCategory() {
// Get a connection and execute the query.
Connection conn = catalogDS.getConnection();
...
}
 

Because of the @Resource annotation, the developer does not need to worry about the boilerplate code that is normally required to get access to the resource. The catalogDS field of the javax.sql.DataSource type is annotated with @Resource and injected by the container prior to the component -- for example, a Servlet -- being made available to the application. The data source JNDI mapping is inferred from the catalogDS field name and javax.sql.DataSource type. Moreover, the catalogDS resource no longer needs to be defined in the deployment descriptor. Slick!

What Can Be Injected?

The support for injection is pervasive throughout the Java EE 5 platform. Many Java Community Process (JCP) program specifications have collaborated to define the various types of injections that the platform supports.

Chapter 5 of JSR 244, the Java platform specification, describes how applications declare dependencies on external resources and configuration parameters, how those items are represented in the Java EE 5 platform naming system, and how they can be injected into application components. This chapter puts in perspective everything related to the platform's resource access.

Further, Section 14.5 of the Servlet specification discusses the injection annotations that are supported in the Java EE 5 platform's web technologies. Table 1 lists the supported annotations.

Table 1: Annotations and Their Uses
 
 
Type of Annotation Annotation Name Action or Definition
Common annotations1
@Resource
Declares a reference to a resource such as a data source, Java Messaging Service (JMS) destination, or environment entry. This annotation is equivalent to declaring a resource-ref, message-destination-ref, env-ref, or resource-env-ref element in the deployment descriptor.
 
@Resources
A collection of sorts to allow the declaration of multiple @Resource annotations.
 
@DeclaresRoles
Specifies security roles that the application uses.
 
@RunAs
Specifies the application's role during execution within a Java EE technology environment. Within the scope of the web tier, this annotation can be declared only on a Servlet and is the equivalent of declaring a run-as element on a Servlet in the deployment descriptor.
 
@PostConstruct
Specifies a method that the container will invoke after resource injection is complete but before any of the component's life-cycle methods are called.
 
@PreDestroy
Specifies a method that the container will invoke before removing the component from service.
EJB beans2
@PersistenceContext
Specifies the container-managed entity context.
 
@PersistenceContexts
A collection of sorts to allow the declaration of multiple @PersistenceContext annotations.
 
@PersistenceUnit
Specifies a reference to an entity manager factory for use with EJB beans specified in a component.
 
@PersistenceUnits
A collection of sorts to allow the declaration of multiple @PersistenceUnit annotations.
Web services3
@WebServiceRef
Specifies a reference to a web service within a web component.
 
@WebServicesRefs
A collection of sorts to allow the declaration of multiple @WebServiceRef annotations.
 

1Common annotations: JSR 250, Common Annotations for the Java Platform Specification, provides the semantics of the platform's common annotations.
2EJB beans: See JSR 220, the Enterprise JavaBeans 3.0 Specification, Section 8.1, Annotation of Context Dependencies.
3Web services: See JSR 224, the Java API for XML-Based Web Services (JAX-WS) 2.0 Specification, Section 7.9, javax.xml.ws.WebServiceRef.

What Components Can Accept Resource Injections?

Keep in mind that a Java EE 5 platform container can handle the injections transparently only when they are used on container-managed components, such as EJB beans, Servlets, and JavaServer Pages (JSP) technology tag handlers.

This is for two reasons. First, for performance considerations, a container can restrict its search of annotations only to the components it manages, which are defined in a deployment descriptor or are accessible in specific classpath locations. Second, the container must have control over the creation of the component to be able to transparently perform the injection into the component.

Although resource injection would be most useful in the web tier if it were applicable to any Plain Old Java Object (POJO), this will have to wait for a future release. Table 2 lists the web-tier-managed components that support resource injection in applications based on the Java EE 5 platform.

Table 2: Components That Support Resource Injection
 
 
Name Interface or Class
Servlets
javax.servlet.Servlet
 
 
Servlet filters
javax.servlet.ServletFilter
 
 
Event listeners
javax.servlet.ServletContextListener
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionBindingListener
 
 
Taglib tag handlers
javax.servlet.jsp.tagext.JspTag
 
 
JavaServer Faces technology-managed beans
Plain Old Java Objects (POJOs)
 

JSP technology pages and tag files cannot accept resource injections either.  Because such pages are usually compiled only after receiving a request, an annotation included in a JSP technology page would not be available to the container at deployment time when resource injection occurs.

Tag library validators (TLVs) and TagExtraInfo (TEI) are other classes that the JSP technology container manages, but because their life cycle is limited to the compilation of the JSP technology pages, they are not valid candidates for injection.

Supporting resource injection on JavaServer Faces technology renderers, converters, or validators is not desirable because that would violate Model-View-Controller (MVC) separation of these presentation objects.  If these classes need to get access to resources, they should do so through a managed bean.

Sample Code

A Simple Servlet

The classic first Servlet can now do more than just display the usual Hello World! message. It can easily display an entry from its Java EE 5 platform environment.

private @Resource String welcomeMessage;

public class HelloWorld extends HttpServlet {

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println(welcomeMessage);
}

<env-entry>
<env-entry-name>welcomeMessage</env-entry-name>
<env-entry-type>java.lang.String</env-entry-name>
<env-entry-value>Hello World from env-entry!</env-entry-value>
</env-entry>
 

A JavaServer Faces Technology-Managed Bean

The following example demonstrates the use of the @Resource annotation along with the life-cycle annotations @PostConstruct and @PreDestroy to simulate, in a simplified way, an EJB bean.

The managed bean has access to a DataSource object through the presence of the @Resource annotation. Next, it uses that DataSource to initialize itself with the annotated initBean() method before the managed bean is put into scope. The managed bean then uses the DataSource once again in the annotated flush() method to flush the data back to the database when the bean is removed from scope, that is, when the user has logged or timed out.

private @Resource javax.sql.DataSource userDS ;

public class UserDataBean {

// Ivars pertaining to the user

@PostConstruct
public void initBean() {
Connection conn = userDS.getConnection();
// Use the connection to populate UserDataBean ivars.
}

@PreDestroy
public void flush() {
Connection conn = userDS.getConnection();
// Use the connection to flush any modified ivars
// to the back end.
}

}

<managed-bean>
<managed-bean-name>userdata</managed-bean-name>
<managed-bean-class>somepkg.UserDataBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-bean>
 
Conclusion

As this article demonstrates, the support for resource injection in the web tier makes accessing resources from web applications significantly easier. Try it out. You'll probably be pleased with the amount of time and the number of lines of code you save. Meanwhile, watch for the next article in the "Web Tier to Go With Java EE 5" series, which will describe the new pound syntax introduced in the Unified Expression Language (UEL).

【Java EE】--Contexts and Dependency Injection (上下文与依赖注入)04

使用范围对于Web应用程序来使用注入另一个bean类的bean,bean需要能够在用户与应用程序交互的持续时间内保持状态。 定义这个状态的方法是给bean一个范围。 您可以给对象表23-1中描述的任何...
  • jing18033612052
  • jing18033612052
  • 2017年05月16日 15:33
  • 297

Eclipse报错:Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules

部署了tomcat服务器在Eclipse上面,遇到这个烦人的错误, 按照如下的措施就可以解决这个问题了: 将文件org.eclipse.wst.common.project.facet.core....
  • tom_code
  • tom_code
  • 2017年07月10日 20:08
  • 573

myeclipse导入java EE 5 Library

Build Path=>configure Build Path...=>Libraries=> Add Library...=>选择MyEclipse Libraries=>勾选上 Java EE...
  • qq_26222859
  • qq_26222859
  • 2015年08月04日 13:12
  • 971

解决Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules项目无法加入到tomcat

解决Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules 无法加入到tomcat中问...
  • bpqdwo
  • bpqdwo
  • 2017年06月10日 16:07
  • 1309

Injection of resource dependencies failed解决办法总结

Posted on 2013-12-20 21:24 Hyunji 阅读(82602) 评论(2) 编辑 收藏 今天调试项目代码,出现的引resource的报错,查原因查了好长时间才找到,现...
  • py941215
  • py941215
  • 2017年10月21日 17:51
  • 453

go语言 运行go文件时,报错Resource doesn't have a corresponding Go package的处理方法

好不容易照网上的方法,坎坎坷坷终于把环境搭建好了,新建了一个go文件,运行时,报错:Resource doesn't have a corresponding Go package。 方法一:go文...
  • gongchangwa
  • gongchangwa
  • 2017年10月13日 14:05
  • 435

解决Resource doesn't have a corresponding Go package.问题

首先上图 这个报错主要是程序要启动没有入口的原因,package main下边的mian方法才是一个程序的入口。这就要 修改目录结构如下图修改并运行就可以了...
  • tbc123tbc
  • tbc123tbc
  • 2018年01月12日 18:19
  • 75

eclipse运行go文件,报错“Resource donesnt have a corresponding Go paceage.”

一路磕磕绊绊的,终于完成了eclipse集成个golang开发环境,终于可以开心的码下“Hello World!”了,但是蛋疼的事情又发生了,我发现我总是和报错为伍呐。 Q:      我是项目目...
  • u011968063
  • u011968063
  • 2016年05月12日 22:47
  • 3918

Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules 解决办法

用eclipse做项目时,在Dynamic web module version栏里选择了最新的3.0版本。到了部署项目时就出现了Tomcat version 6.0 only supports J2...
  • iqijun
  • iqijun
  • 2013年12月02日 14:08
  • 6303

Injection of resource dependencies failed;错误几种解决方法

Error creating bean with name 'connDataController': Injection of resource dependencies failed; 最近研究...
  • qq_34735535
  • qq_34735535
  • 2017年07月25日 10:34
  • 2406
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Web Tier to Go With Java EE 5: A Look at Resource Injection
举报原因:
原因补充:

(最多只允许输入30个字)