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

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

Java EE6装饰器:在注入时装饰类相关推荐

  1. java与java ee_Java EE6装饰器:在注入时装饰类

    java与java ee 软件中常见的设计模式是装饰器模式 . 我们上一堂课,然后在它周围包装另一堂课. 这样,当我们调用类时,我们总是在到达内部类之前通过周围的类. Java EE 6允许我们通过C ...

  2. python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景

    装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...

  3. python自带装饰器详解_Python装饰器详解

    引言 装饰器简单来说是我们向一个现有的已经存在的函数或对象添加新的功能,同时呢我们又不用改变他现有的结构. 为什么我们需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye( ...

  4. python装饰器与闭包_Python 装饰器和闭包

    Python 装饰器和闭包 装饰器是 Python 中常见的语法糖,这篇文章讲了闭包和装饰器的原理,并且分析了函数中变量的作用域,以及尝试总结了常见的坑. 装饰器基础 首先来看看装饰器的定义:装饰器本 ...

  5. python装饰器实例-Python函数装饰器--实例讲解

    一.装饰器定义: 1.装饰器的本质为函数: 2.装饰器是用来完成被修饰函数的附加功能的 所以:装饰器是用来完成被修饰函数附属功能的函数 装饰器的要求: 1.不能修改被修饰函数的源代码: 2.不能更改被 ...

  6. python中的装饰器有哪些-python 装饰器以及开发中常用的例子

    有时候我们想为多个函数,同意添加某一种功能,比如及时统计,记录日志,缓存运算结果等等,而又不想改变函数代码 那就定义装饰器函数,用它来生成一个在原函数基础添加了新功能的函数,代替原函数 参考金角大王的 ...

  7. python装饰器函数-python函数装饰器

    什么是装饰器 装饰器是一个可调用的对象,其参数是另一个函数(被装饰的函数).装饰器可能会: 1,处理被装饰的函数,然后把它返回 2,将其替换成另一个函数或者对象 若有个名为decorate的装饰器,则 ...

  8. python装饰器-如何理解Python装饰器?

    我从以下几点,由浅入深详细讲解一下Python装饰器:什么事装饰器? 为什么用装饰器? 在哪里用装饰器? 然后以示例+讲解相结合的方式阐述,同时会讲解一些在很多教程和书籍中不会涉及到的内容. 什么是P ...

  9. python装饰器函数-python装饰器1:函数装饰器详解

    先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函数 方法 类 基础:函数装饰器的表现方式 假如你已经定义了 ...

最新文章

  1. java将一个数转成36进制的数_编程实现将一个N进制数转换成M进制数。
  2. python画三维立体图-Python+matplotlib绘制三维图形5个精选案例
  3. Python命名空间
  4. (四)学习CSS之position、bottom、left、right和top属性
  5. iptables详解(13):iptables动作总结之二
  6. [2021.1.27多校省选模拟10]跑步(线段树合并)
  7. python模块学习之glob模块
  8. Cheat Engine 教程( 1 - 9 通关 )
  9. 信息学奥赛C++语言: 数字三角形1
  10. 字符串匹配(二)——逆向思维 BMH
  11. 【clickhouse】clickhouse时区
  12. 当我们谈微服务,我们在谈什么?谈谈我对微服务的理解!
  13. 2018-2019-1 20165208 《信息安全系统设计基础》第5周学习总结
  14. iOS 本地推送以及自定义推送声音
  15. office2010 反应慢_office2010打开时间太慢。怎么办?
  16. nodejs调用google翻译api
  17. 这些中国扶贫路上的“组合拳”,你见过吗?
  18. 打开组策略 计算机配置,组策略怎么打开? 打开组策略命令与4种方法-电脑教程...
  19. 雷达干扰技术(二)数字干扰合成及相关技术
  20. 教你快速查询大量圆通快递单号的物流信息

热门文章

  1. java native关键字(java本地方法)
  2. java程序连接kafka_Java的Kafka:构建安全,可扩展的消息传递应用程序
  3. java更好的语言_五个使Java变得更好的功能
  4. 什么是openstack_您在OpenStack Summit 2016上错过了什么
  5. intellij idea_IntelliJ IDEA内部设计
  6. 通过Spring集成进行消息处理
  7. lucene使用3.0.3_Apache Lucene 5.0.0即将发布!
  8. ejb生命周期_EJB 3.x:生命周期和并发模型(第2部分)
  9. 使用JUnit 5进行更清洁的参数化测试
  10. 固定速率与固定延迟– RxJava常见问题解答