软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入

上传人:枫** 文档编号:569326293 上传时间:2024-07-28 格式:PPT 页数:65 大小:816.50KB
返回 下载 相关 举报
软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入_第1页
第1页 / 共65页
软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入_第2页
第2页 / 共65页
软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入_第3页
第3页 / 共65页
软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入_第4页
第4页 / 共65页
软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入_第5页
第5页 / 共65页
点击查看更多>>
资源描述

《软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入》由会员分享,可在线阅读,更多相关《软构件与中间件技术Java EE:第5章 Java EE平台上下文和依赖注入(65页珍藏版)》请在金锄头文库上搜索。

1、第5章 Java EE平台上下文和依赖注入吉林大学软件学院本章内容安排:5.1上下文和依赖注入的概念5.2上下文和依赖注入应用实例5.1上下文和依赖注入的概念5.1.1什么是上下文和依赖注入 Java EE平台上下文和依赖注入(Contexts and Dependency Injection,CDI)是Java EE 6最重要的特征之一,也是Java EE 6的新技术之一。上下文和依赖注入提供了一个体系结构,以允许如Servlet、企业bean和JavaBeans这样的Java EE生产者组件在具有明确定义范围的应用程序生命周期内存在。5.1上下文和依赖注入的概念5.1.1什么是上下文和依赖

2、注入 上下文和依赖注入由JSR 299(Contexts and Dependency Injection for the Java EE Platform 1.0)定义,JSR 330(Dependency Injection for Java)为依赖注入提供了一个标准、可扩展的API,JSR 299则建立在JSR 330之上,统一并简化了EJB与JSF编程模型。5.1上下文和依赖注入的概念5.1.1什么是上下文和依赖注入 上下文和依赖注入能够提供的基本服务包括:上下文(Contexts):将有状态组件的生命周期和交互与良好定义的可扩展的生命周期上下文绑定的能力依赖注入(Dependency

3、 Injection):以类型安全的方式将组件注入到应用中的能力,包括在部署的时候选择注入特定接口的哪个实现的能力。5.1上下文和依赖注入的概念5.1.1什么是上下文和依赖注入 发布上下文和依赖注入的目的之一是将Java EE平台的Web层和事务处理层之间很好地连接,使得开发者在Web应用中使用企业bean和JSF技术更为容易。上下文和依赖注入的一个重要主题是松耦合,是在Web层和事务处理层之间建立良好交流的手段。在Java EE平台上,Web层的重点是展示,Web技术如JSF和JSP等会渲染用户界面,显示它的内容,但没有集成处理事务资源的工具;借助于EJB和JPA等技术,企业层对事务性资源提

4、供了强大的支持,可以轻松构建与数据库交互的应用程序,在数据上提交事务,持久化数据。上下文和依赖注入使上下文和依赖注入使WebWeb层也支持事务,这层也支持事务,这样在样在WebWeb应用程序中访问事务资源就更容易了。应用程序中访问事务资源就更容易了。5.1上下文和依赖注入的概念5.1.1什么是上下文和依赖注入 上下文和依赖注入建立在Java EE 6新引入的一个名为托管Bean(Managed Bean)的概念之上。5.1上下文和依赖注入的概念5.1.2托管Bean 一、关于bean CDI重新定义了超出如JavaBeans和企业JavaBeans(EJB)技术等其他Java技术中所使用的be

5、an的概念。在CDI中,bean是定义了应用状态和逻辑的上下文对象源。如果它的实例的生命周期可根据CDI规范中定义的生命周期上下文模型由容器管理的话,Java EE组件是一个bean。5.1上下文和依赖注入的概念5.1.2托管Bean更特别地,一个bean还有以下描述:一个非空的bean类型集合一个非空的修饰符集合一个范围可选地,一个bean EL名一个拦截器绑定集合一个bean实现5.1上下文和依赖注入的概念5.1.2托管Bean 几乎任何Java类型都可以是一个bean类型,如:接口、实际类、抽象类、最终类、含有最终方法的类、参数化类型、数组类型。5.1上下文和依赖注入的概念5.1.2托管

6、Bean 二、关于托管bean 一个顶级的Java类是一个托管bean(Managed Bean),如果它通过如JavaServer Faces技术规范等任何其他Java EE技术规范被定义为托管bean,或者符合以下所有条件:不是非静态内部类是一个实际类或标示以Decorator没有被标示为EJB组件定义元注释,没有被用ejb-jar.xml声明为EJB bean类5.1上下文和依赖注入的概念5.1.2托管Bean有一个恰当的构造方法,亦即或者类有一个无参构造方法,或者类用Inject声明了构造方法如无特别声明,在定义托管bean时,元注释是需要的。5.1上下文和依赖注入的概念5.1.2托管

7、Bean 三、bean作为可注入对象 注入的概念成为Java技术的一部分已经有一段时间了。自从Java EE 5平台面世,元注释已经使得注入资源和其他一些种类的对象到容器管理的对象成为可能。CDI使得注入更多种类的对象和注入它们到非容器管理对象成为可能。以下种类的对象可以被注入:任何Java类会话bean5.1上下文和依赖注入的概念5.1.2托管BeanJava EE资源:数据源、Java消息服务题目,队列,连接工厂持久性上下文生产者域生产者方法返回的对象Web服务引用远程企业bean引用5.1上下文和依赖注入的概念5.1.2托管Bean一个基础的Java类程序清单5.1public clas

8、s Greeting public String greet(String name) return Hello, + name + .; 下面的内容就是讨论如何将这个类注入另一个类。5.1上下文和依赖注入的概念5.1.3完善注入的手段 一、使用修饰符 可以使用修饰符(Qualifiers)提供一系列特定bean类型实现,一个修饰符就是提供给bean的一个元注释。确切地说,一个修饰符类型就是一个定义成如Target(METHOD, FIELD, PARAMETER, TYPE)和Retention(RUNTIME)那样的元注释。5.1上下文和依赖注入的概念5.1.3完善注入的手段 定义一个“I

9、nformal”修饰符类型,并在一个类的定义中使用它的代码: 程序清单5.2public interface Informal 可以用它来定义一个Greeting类的扩展类。5.1上下文和依赖注入的概念5.1.3完善注入的手段程序清单5.3Informalpublic class InformalGreeting extends Greeting Override public String greet(String name) return Hi, + name + !; 使用了新定义的修饰符覆盖定义了父类的方法5.1上下文和依赖注入的概念5.1.3完善注入的手段 在CDI规范下,如果类定义

10、时不使用修饰符,则相当于使用了一个默认修饰符“Default”。所以,程序清单5.1中的代码相当于如下所示的代码。程序清单5.4Defaultpublic class Greeting public String greet(String name) return Hello, + name + .; 5.1上下文和依赖注入的概念5.1.3完善注入的手段 定义bean是为了使用bean,可以依据CDI规范将其注入到另外一个应用中去,如可以定义另外一个bean名为Printer,向其中注入名为Greeting的bean。 两种注入方式: 程序清单5.5注入的是程序清单5.1中定义的Greetin

11、g类的实现。 程序清单5.6注入的是程序清单5.3中定义的Greeting类的实现,因为使用了Informal修饰符。5.1上下文和依赖注入的概念5.1.3完善注入的手段 二、使用范围 对于一个使用注入了另一个bean的bean的Web应用而言,被使用的bean需要在用户与Web应用交互的整个期间保持状态。定义这个状态的途径是给与bean一个范围(Scopes)。可以将以下任何一个范围描述赋予一个对象,究竟赋予那个描述取决于如何使用它。具体的范围描述见表5.1。5.1上下文和依赖注入的概念5.1.3完善注入的手段 范围的元注释和持续时间范围范围元注释元注释持续时间持续时间RequestRequ

12、estScoped用户与Web应用之间单个HTTP请求的交互SessionSessionScoped用户与Web应用之间跨越多个HTTP请求的交互ApplicationApplicationScoped跨越所有用户与Web应用之间的交互的共享状态DependentDependent没有定义时的默认范围,这意味着一个存在的对象正确地服务于一个客户端并且与客户端有相同的生命周期ConversationConversationScoped用户与JavaServer Faces应用之间的交互,在明确的开发者控制的跨越JavaServer Faces生命周期的多次调用边界内。所有长运行的对话是一个特定的

13、HTTP servlet会话的范围,不得交叉会话边界。5.1上下文和依赖注入的概念5.1.3完善注入的手段 也可以定义并实现用户范围,但这是一个高级话题。用户范围可能被用于那些实施和扩大CDI规范。范围给了对象一个良好定义的生命周期上下文。范围对象当需要时可被自动生成,当其所在的上下文被创建完时可被自动销毁。此外,它的状态自动被运行于同一个上下文的客户端所共享。5.1上下文和依赖注入的概念5.1.3完善注入的手段 如servlets和企业bean的Java EE组件,和JavaBeans组件都没有一个良好定义的范围,包括:单身,无状态对象,必须被客户端明确生成和销毁的对象,像JavaBeans

14、组件和有状态bean。 如果创建一个是托管bean的Java EE组件,它即成为一个存在于良好定义的上下文中的范围对象。5.1上下文和依赖注入的概念5.1.3完善注入的手段 使用Printer的Web应用将使用简单的请求和应答机制,所以托管bean可以如下标示。RequestScopedpublic class Printer Inject Informal Greeting greeting; .新增元注释5.1上下文和依赖注入的概念5.1.3完善注入的手段 三、给bean一个EL名 想让前面的Printer通过EL可访问,可以用Named修饰符。这就是给了这个bean一个默认的名字,名字为

15、首字母小写的bean名字符串。这样,一个Facelets页面将会用“printer”名字引用bean。5.1上下文和依赖注入的概念5.1.3完善注入的手段程序清单5.8NamedRequestScopedpublic class Printer Inject Informal Greeting greeting; .新增元注释5.1上下文和依赖注入的概念5.1.3完善注入的手段 还可以使用Named定义非默认名字,将Named修改为Named(MyPrinter)的形式,一个Facelets页面即可使用“MyPrinter”引用bean。5.1上下文和依赖注入的概念5.1.3完善注入的手段 四

16、、添加Setter和Getter方法 让托管bean成为可访问的,还需要向其中添加Setter和Getter方法,使用Setter和Getter方法的好处是可以使类的属性对外不公开,但是还保留了访问属性的手段。Setter和Getter方法一般习惯用SetXXX和GetXXX的方式命名,但是也可以用其他方式。5.1上下文和依赖注入的概念5.1.3完善注入的手段 完整的Printer代码如程序清单5.9import javax.inject.Inject;import javax.enterprise.context.RequestScoped;import javax.inject.Named

17、;NamedRequestScopedpublic class Printer 5.1上下文和依赖注入的概念5.1.3完善注入的手段 Inject Informal Greeting greeting; private String name; private String salutation; public void createSalutation() this.salutation = greeting.greet(name); 5.1上下文和依赖注入的概念5.1.3完善注入的手段 public String getSalutation() return salutation; pub

18、lic void setName(String name) this.name = name; 5.1上下文和依赖注入的概念5.1.3完善注入的手段 public String getName() return name; 5.1上下文和依赖注入的概念5.1.3完善注入的手段 在完成了完整的Printer类的定义之后,就可以在Web层中使用这个bean了。在Facelets页面中使用托管bean,需要生成一个表单使用用户界面元素调用其方法并显示结果。具体的Facelets页面代码在程序清单5.11中给出。5.1上下文和依赖注入的概念5.1.4用生产者方法注入对象 生产者方法(Producer

19、Methods)提供了一种方式来注入那些不是bean的对象,对象的值在运行时可能会有所变化,对象还需要用户初始化。例如,想初始化一个用MaxNumber修饰符定义的数值,可以在托管bean中定义一个值:private int maxNumber = 100;5.1上下文和依赖注入的概念5.1.4用生产者方法注入对象 然后给它定义一个生产者方法getMaxNumber:ProducesMaxNumberint getMaxNumber() return maxNumber;5.1上下文和依赖注入的概念5.1.4用生产者方法注入对象 当将这个对象注入到另外一个托管bean,容器会自动调用生产者方法

20、,初始化数值为100。InjectMaxNumberprivate int maxNumber;如果数值在运行时期间内有变化,处理会略有不同。5.1上下文和依赖注入的概念5.1.4用生产者方法注入对象 下列代码定义了一个生产者方法,生成一个用Random修饰符定义的随机数。程序清单5.105.1上下文和依赖注入的概念5.1.4用生产者方法注入对象private java.util.Random random = new java.util.Random( System.currentTimeMillis() );java.util.Random getRandom() return rando

21、m;Produces Random int next() return getRandom().nextInt(maxNumber);5.1上下文和依赖注入的概念5.1.4用生产者方法注入对象当注入这个对象到另一个托管bean时,声明这个对象的一个上下文实例:InjectRandomInstance randomInt;随后调用实例的get方法:this.number = randomInt.get();5.1上下文和依赖注入的概念5.1.5配置一个CDI应用 使用CDI的应用必须有个名为beans.xml的文件。文件可以完全是空的,但是必须出现,事实上beans.xml只有在某些特定场合才有

22、内容。对于Web应用,beans.xml文件或者在WEB-INF文件夹或者在WEB-INF/classes/META-INF文件夹中;对于EJB或JAR文档,beans.xml文件必须在META-INF文件夹中。5.2上下文和依赖注入应用实例5.2.1simplegreeting实例 这个例子演示了CDI的一些最基本特征:范围、修饰符、注入、在JavaServer Faces应用中访问托管bean等。例子的功能是用户在页面上输入自己的名字,按下“Say Hello”按钮,将会有一句给用户的问候语显示。例子包含三个组成部分:源文件、Facelets页和模板、配置文件。5.2上下文和依赖注入应用实

23、例5.2.1simplegreeting实例 一、源文件 例子共有4个源文件:默认的Greeting类定义,在程序清单5.1中;生产者Informal修饰符接口定义,在程序清单5.2中;InformalGreeting类定义,在程序清单5.3中;Printer托管bean类定义,在程序清单5.9中。5.2上下文和依赖注入应用实例5.2.1simplegreeting实例 二、Facelets页 Facelets页文档index.xhtml的代码:程序清单5.115.2上下文和依赖注入应用实例5.2.1simplegreeting实例 当用户输入了自己的名字时,输入的值被用来作为Printer类

24、的“name”成员的值当用户按下按钮,调用Greeting类的greet方法,输出了一句问候语问候语被输出给输出组件5.2上下文和依赖注入应用实例5.2.1simplegreeting实例 另外,如果分别向Printer类中注入默认版的Greeting类的实现或者是Informal版的实现,问候语将分别显示为“Hello, name.”或“Hi, name!”。 这个例子中,我们看到了源文件中的注入,也看到了表单中以EL名“printer”对于Printer类的方法的调用,实现了从以Facelets页为代表的Web层对以Printer类为代表的业务层的访问,结果是大大增强了Web层的功能。这一

25、切的实现,正是CDI作用的结果。5.2上下文和依赖注入应用实例5.2.1simplegreeting实例 三、模板 程序清单5.12,一个生成页面的范本。 四、配置文件 由于这个例子十分简单,所以它的配置文件几乎就是一个空文件,还有一个部署描述文件位于simplegreeting/web/WEB-INF文件夹。5.2上下文和依赖注入应用实例5.2.2guessnumber实例 这个例子演示了生产者方法的使用,演示了会话和应用范围。例子是一个小游戏,用户在10次尝试内猜到一个数字。 例子含有4个源文件、Facelets页、模板、配置文件。模板和配置文件与上一个例子的模板和配置文件相同。5.2上下

26、文和依赖注入应用实例5.2.2guessnumber实例 一、源文件 MaxNumber修饰符接口定义:程序清单5.13 Random修饰符接口定义:程序清单5.14 Generator托管bean定义:程序清单5.15 UserNumberBean托管bean定义:程序清单5.165.2上下文和依赖注入应用实例5.2.2guessnumber实例 Generator托管bean中使用了MaxNumber修饰符和Random修饰符,并且使用Produces元注释声明了两个生产者方法。5.2上下文和依赖注入应用实例5.2.2guessnumber实例 UserNumberBean托管bean也是

27、JavaServer Faces应用的backing bean,其中的check方法和validateNumberRange方法给出了游戏的基本逻辑。5.2上下文和依赖注入应用实例5.2.2guessnumber实例import java.io.Serializable;import javax.annotation.PostConstruct;import javax.enterprise.context.SessionScoped;import javax.enterprise.inject.Instance;import javax.inject.Inject;import javax.

28、inject.Named;import javax.faces.application.FacesMessage;import ponent.UIComponent;5.2上下文和依赖注入应用实例5.2.2guessnumber实例import ponent.UIInput;import javax.faces.context.FacesContext;SessionScopedNamedpublic class UserNumberBean implements Serializable private static final long serialVersionUID = 1L; Inj

29、ect /依赖注入 Random5.2上下文和依赖注入应用实例5.2.2guessnumber实例 Instance randomInt; private Integer userNumber; Inject /依赖注入 MaxNumber private int maxNumber; private int maximum; private int minimum; private int number; private int remainingGuesses;5.2上下文和依赖注入应用实例5.2.2guessnumber实例 public UserNumberBean() /默认构造方法

30、 public int getNumber() return number; public void setUserNumber(Integer user_number) userNumber = user_number; 5.2上下文和依赖注入应用实例5.2.2guessnumber实例 public Integer getUserNumber() return userNumber; public int getMaximum() return (this.maximum); 5.2上下文和依赖注入应用实例5.2.2guessnumber实例 public void setMaximum(

31、int maximum) this.maximum = maximum; public int getMinimum() return (this.minimum); 5.2上下文和依赖注入应用实例5.2.2guessnumber实例 public void setMinimum(int minimum) this.minimum = minimum; public int getRemainingGuesses() return remainingGuesses; 5.2上下文和依赖注入应用实例5.2.2guessnumber实例 public String check() throws I

32、nterruptedException if (userNumber number) maximum = userNumber - 1; if (userNumber number) minimum = userNumber + 1; 5.2上下文和依赖注入应用实例5.2.2guessnumber实例 if (userNumber = number) FacesContext.getCurrentInstance() .addMessage( null, new FacesMessage(Correct!); remainingGuesses-; return null; 5.2上下文和依赖注

33、入应用实例5.2.2guessnumber实例 PostConstruct /定义为生命周期回调方法 public void reset() this.minimum = 0; this.userNumber = 0; this.remainingGuesses = 10; this.maximum = maxNumber; this.number = randomInt.get(); 5.2上下文和依赖注入应用实例5.2.2guessnumber实例 public void validateNumberRange( /定义用户验证器 FacesContext context, UICompo

34、nent toValidate, Object value) if (remainingGuesses = 0) FacesMessage message = new FacesMessage(No guesses left!); context.addMessage( toValidate.getClientId(context),message);5.2上下文和依赖注入应用实例5.2.2guessnumber实例 (UIInput) toValidate).setValid(false); return; int input = (Integer) value; if (input max

35、imum) (UIInput) toValidate).setValid(false);5.2上下文和依赖注入应用实例5.2.2guessnumber实例 FacesMessage message = new FacesMessage(Invalid guess); context.addMessage( toValidate.getClientId(context), message); 5.2上下文和依赖注入应用实例5.2.2guessnumber实例 二、Facelets页 页面的操作主要体现在表单中,分析一下各个组件的EL表达式很容易理解这个应用。value=#userNumberBean.userNumber“validator=#userNumberBean.validateNumberRange“action=#userNumberBean.check“action=#userNumberBean.reset“注意理解页面上所使用的EL表达式。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号