Java EE6装饰器:在注入时装饰类

软件中常见的设计模式是装饰器模式 。 我们上一堂课,然后在它周围包装另一堂课。 这样,当我们调用类时,我们总是在到达内部类之前经过周围的类。

Java EE 6允许我们通过CDI创建装饰器,作为其AOP功能的一部分。 如果我们想实现仍然与业务足够接近的跨领域关注点 ,则可以使用Java EE 6的此功能。

假设您有一项票务服务,可让您订购特定事件的票务。 TicketService处理注册等,但是我们要添加餐饮。 我们不认为这是门票订购逻辑的一部分,因此我们创建了一个装饰器。 装饰者将调用TicketService并添加门票数量。

界面:

public interface TicketService {Ticket orderTicket(String name);
}

接口的实现,创建票证并将其保留。

@Stateless
public class TicketServiceImpl implements TicketService {@PersistenceContextprivate EntityManager entityManager;@TransactionAttribute@Overridepublic Ticket orderTicket(String name) {Ticket ticket = new Ticket(name);entityManager.persist(ticket);return ticket;}
}

当我们不能使用装饰器时,我们可以创建相同接口的新实现。

@Decorator
public class TicketServiceDecorator implements TicketService {@Inject@Delegateprivate TicketService ticketService;@Injectprivate CateringService cateringService;@Overridepublic Ticket orderTicket(String name) {Ticket ticket = ticketService.orderTicket(name);cateringService.orderCatering(ticket);return ticket;}
}

请注意,我们在此处应用了2个CDI特定注释。 @Decorator将实现标记为装饰器。 装饰器应始终具有一个委托(我们要装饰的类),该委托带有@Delegate批注(在注入点处)标记。 还要注意我们使用接口而不是实现的事实。

就像其他示例一样 ,当您注入此接口时,将使用常规实现。

@Inject private TicketService ticketService;

无需使用限定符,我们只需要调整beans.xml即可将TicketServiceDecorator标记为“ Decorator”。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"><decorators><class>be.styledideas.blog.decorator.TicketServiceDecorator</class></decorators>
</beans>

作为更高级的用法,我们可以组合多个装饰器并选择我们希望它们执行的顺序。

如果您有用例,则可以像这样在bean.xml文件中定义两个装饰器,从而轻松定义它们。

<decorators><class>be.styledideas.blog.decorator.HighDecorator</class><class>be.styledideas.blog.decorator.LowDecorator</class>
</decorators>

因此,当我们调用装饰类时,我们会得到高级装饰器条目,低装饰器条目,实际装饰器类,低装饰器出口,高装饰器出口。 因此,文件中的装饰器顺序确实很重要。

第二个功能比第一个功能更具吸引力,它展示了Java EE6中Decorator功能的真正威力。 这是将其与CDI批注结合在一起的能力。 作为示例,我将使用社交媒体供稿处理器。

所以我创建了一个接口:

public interface SocialFeedProcessor {Feed process(String feed);
}

并提供了2种实现,twitter和google +

public class TwitterFeedProcessor implements SocialFeedProcessor{@Overridepublic Feed process(String feed) {System.out.println("processing this twitter feed");// processing logicsreturn new Feed(feed);}}
public class GooglePlusFeedProcessor implements SocialFeedProcessor {@Overridepublic Feed process(String feed) {System.out.println("processing this google+ feed");// processing logicsreturn new Feed(feed);}}

我将按照此处所述通过自定义限定符对这2个bean进行注释

@javax.inject.Qualifier
@java.lang.annotation.Retention(RUNTIME)
@java.lang.annotation.Target({FIELD, PARAMETER, TYPE})
@java.lang.annotation.Documented
public @interface FeedProcessor {
}

然后用它注释我的两个处理器。

@FeedProcessor
public class TwitterFeedProcessor implements SocialFeedProcessor{@Overridepublic Feed process(String feed) {System.out.println("processing this twitter feed");// processing logicsreturn new Feed(feed);}}
@FeedProcessor
public class GooglePlusFeedProcessor implements SocialFeedProcessor {@Overridepublic Feed process(String feed) {System.out.println("processing this google+ feed");// processing logicsreturn new Feed(feed);}}

没什么特别的,但是现在当我们编写装饰器时,我们使用CDI的功能仅用@FeedProcessor注释装饰类。

@Decorator
public class SocialFeedDecorator implements SocialFeedProcessor {@Delegateprivate @FeedProcessor SocialFeedProcessor processor;@Overridepublic Feed process(String feed) {System.out.println("our decorator is decorating");return processor.process(feed);}
}

剩下的唯一事情就是在beans.xml中注册装饰器

<decorators><class>be.styledideas.blog.decorator.SocialFeedDecorator</class>
</decorators>

通过使用注释,我们可以使用该装饰器自动装饰我们的SocialfeedProcessor的所有实现。 当我们添加不带注释的SocialFeedProcessor的额外实现时,将不装饰Bean。

参考: Java EE6装饰器,在注入时装饰类, Java EE6装饰器,来自Styled Ideas Blog的 JCG合作伙伴 Jelle Victoor的 高级用法 。

相关文章 :
  • JDK中的设计模式
  • 在域驱动设计中使用状态模式
  • 基本的EJB参考,注入和查找
  • 使用Spring AOP进行面向方面的编程
  • 使用Spring AspectJ和Maven进行面向方面的编程

翻译自: https://www.javacodegeeks.com/2011/10/java-ee6-decorators-decorating-classes.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言代码规范(六)浮点型变量逻辑比较

无论是float还是double类型的变量&#xff0c;都有精度限制。所以一定要避免将浮点变量用""或"!"与数字比较&#xff0c;应该设法转化成为">"或"<"形式。 不建议使用的例子&#xff1a; if(0.0 x) if(0.0 ! x) 强烈推荐的例…

图灵机器人调用数据恢复_机器人也能撩妹?python程序员自制微信机器人,替他俘获女神芳心...

机器人也有感情还记得王传君饰演的《星语心愿之再爱》这部电影吗&#xff1f;王传君饰演的天才程序员“王鹏鹏”因工作原因不能陪伴照顾身在异地的女朋友“林亦男”&#xff0c;呆萌宅男“王鹏鹏”开发出一款以自己为原型的“王鹏鹏8.0”程序去陪伴异地恋的女友&#xff0c;后来…

Spark排错与优化

一. 运维 1. Master挂掉,standby重启也失效 Master默认使用512M内存&#xff0c;当集群中运行的任务特别多时&#xff0c;就会挂掉&#xff0c;原因是master会读取每个task的event log日志去生成spark ui&#xff0c;内存不足自然会OOM&#xff0c;可以在master的运行日志中看到…

在MySQL上使用带密码的GlassFish JDBC安全性

我在该博客上最成功的文章之一是有关在GlassFish上使用基于表单的身份验证来建立JDBC安全领域的文章 。 对这篇文章的一些评论使我意识到&#xff0c;要真正使它安全&#xff0c;应该做的还很多。 开箱即用的安全性 图片&#xff1a; TheKenChan &#xff08; CC BY-NC 2.0 &a…

mgo写入安全机制

mgo写入安全机制 mongo写入安全mgo写入安全mongo写入安全 mongo本身也有一整套的写入安全机制,但是在这篇的内容里只介绍一小部分相关部分.先放一个链接可以跳过本节不看直接看这个 链接. WriteConcern.NONE:没有异常抛出WriteConcern.NORMAL:仅抛出网络错误异常&#xff0c;没…

C学习杂记(二)笔试题:不使用任何中间变量如何将a、b的值进行交换

常见的方法如下 void swap1(int *a, int *b) {int temp *a;*a *b;*b temp; } 不使用中间变量的方法 void swap2(int *a, int *b) {*a *a *b;*b *a - *b;*a *a - *b; } 这种方法是不可取的&#xff0c;因为ab和a-b的运算可能会导致数据溢出。 void swap3(int *a, in…

利用python进行数据分析_利用python进行数据分析复现(1)

&#xfeff;一直以来&#xff0c;都想学习python数据分析相关的知识&#xff0c;总是拖拖拉拉&#xff0c;包括这次这个分享也是。《利用python进行数据分析 第2版》是一次无意之间在简书上看到的一个分享&#xff0c;我决定将很详细。一直都想着可以复现一下。但总有理由&…

在运行时交换出Spring Bean配置

如今&#xff0c;大多数Java开发人员都定期与Spring打交道&#xff0c;而我们当中的许多人已经熟悉了Spring的功能和局限性。 最近&#xff0c;我遇到了一个我从未遇到过的问题&#xff1a;引入了基于运行时引入的配置来重新连接Bean内部的功能。 这对于简单的配置更改或交换掉…

Proximal Algorithms--Accelerated proximal gradient method

4.3 Accelerated proximal gradient method&#xff1a; 加速近端梯度方法&#xff1a; 基本的近端梯度方法的所谓的“加速”版本&#xff0c;就是在算法中包含了一个外推(extrapolation)步骤&#xff0c;一个简单的版本是&#xff1a; yk1:xkωk(xk−xk−1)xk1:proxλkg(yk1−…

C语言代码规范(七)#define

#define 宏定义的使用 #define MAX(x, y) ( ((x) > (y)) ? (x) : (y) ) #define MIN(x, y) ( ((x) < (y)) ? (x) : (y) ) 在宏定义中要把参数用括号扩起来( ((x) > (y)) ? (x) : (y) )。 因为宏只是简单的文本替换&#xff0c;如果不注意&#xff0c;很容…

http 二进制_浅谈HTTP协议

HTTP一、HTTP协议http协议&#xff0c;是超文本传输协议&#xff0c;此协议是基于TCP/IP的协议&#xff0c;是互联网上应用最为广泛的一直网络协议是一种无状态协议&#xff0c;默认端口为80,。设计HTTP的最初目的是为了提供一种发布和接受HTML页面的方法。通过HTTP或者HTTPS协…

登陆注册

登陆注册&#xff0c;注册的账号存在服务器的数据库里&#xff0c;成功了就给你返回成功&#xff0c;失败了就返回失败 有三种登陆方式&#xff1a;普通注册&#xff0c;手机号注册&#xff0c;第三方注册转载于:https://www.cnblogs.com/SensenCoder/p/4885606.html

Java并发教程–线程池

Java 1.5中提供的最通用的并发增强功能之一是引入了可自定义的线程池。 这些线程池使您可以对诸如线程数&#xff0c;线程重用&#xff0c;调度和线程构造之类的东西进行大量控制。 让我们回顾一下。 首先&#xff0c;线程池。 让我们直接进入java.util.concurrent.ExecutorSer…

HTTPPost/AFNetWorking/JSONModel/NSPredicate

一、HTTPPost 1. POST方式发送请求 HTTP协议下默认数据发送请求方法是GET方式&#xff0c;若需要使用POST方法&#xff0c;则需要对发送的请求也就是request对象&#xff0c;进行属性设置。 步骤如下&#xff1a; > 要发送的请求对象&#xff0c;需要使用可变请求对象 [[NSM…

C语言代码规范(八)使用const修饰值不允许改变的变量

使用const限定一个变量的值不允许被改变&#xff0c;从而保护被修饰的东西&#xff0c;防止意外&#xff0c;提高程序的可靠性和安全性。

教育小思

父母的时代是“攒钱&#xff0c;买房&#xff0c;生子&#xff0c;终老”&#xff0c;而现在的时代是“教育&#xff0c;创造&#xff0c;传承&#xff0c;成长”。 改变世界&#xff0c;从教育起步。 传统教育的不足之处&#xff1a; 1. 学习体验不佳&#xff0c;学习者被迫…

linux redis客户端_为什么单线程Redis能那么快?

我们通常说&#xff0c;Redis 是单线程&#xff0c;主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的&#xff0c;这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能&#xff0c;比如持久化、异步删除、集群数据同步等&#xff0c;其实是由额外的线…

servlet中文乱码处理

servlet中文乱码处理 如果是post设置req.setCharacterEncoding("utf-8");如果是get&#xff0c;不去修改服务器配置的情况下new String(name.getBytes("iso-8859-1"),"utf-8")数据库乱码?useUnicodetrue&characterEncodingUTF-8转载于:http…

C语言开发笔记(七)const和指针

const修饰变量是常用的&#xff0c;不容易犯错&#xff0c;而const和指针一起使用时很容易混淆。 (一)const int *p #include <stdio.h>int main(void) {int a 10;int b 20;const int *p &a;*p b;return 0; } const在int *的左侧&#xff0c;即指针指向内容为…

从JavaFX 1.3迁移到JavaFX 2.0

几天前&#xff0c;我完成了将Modellus的源代码从JavaFX 1.3脚本迁移到JavaFX 2.0 Java语言的过程。 因此&#xff0c;我认为写关于我在此过程中学到的知识会很好。 我想指出&#xff0c;如果您想继续在JavaFX 2.0中使用JavaFX脚本&#xff0c;则可以使用Visage&#xff1a; ht…