CDI services--Decorators(装饰器)
1.Decorators装饰器综述
拦截器是一种强大的方法在应用程序捕捉运行方法和解耦。拦截器可以拦截任何java类型的调用.
这使得拦截器适合解决事务管理,安全性,以及日记记录.
本质上说,拦截器并不知道他们截获的实际语义事件.因此,拦截器并不是很适合和系统的业务挂钩.
而本章的装饰器,则又不一样.
装饰器只截取调用某个Java接口,因此获知这个接口的所有语义连接。
decorator直接实现与业务语义操作,这也意味着装饰没有拦截器的通用性。
拦截器和修饰符,尽管在很多方面相似,是互补的。但decorator无法解决技术问题,横跨许多不同的类型。
假设我们有一个接口,代表账户:
|
1
2
3
4
5
6
|
public interface Account { public BigDecimal getBalance(); public User getOwner(); public void withdraw(BigDecimal amount); public void deposit(BigDecimal amount);} |
几种不同的Bean在我们系统实现账户接口。
然而,我们有一个强制要求:任何类型的账户,交易必须由系统日志进行记录.
这就是装饰器的一个工作.
用@Decorator标注一个bean(甚至可能是一个抽象类),这样就表明此类是装饰器.
|
1
2
3
4
|
@Decoratorpublic abstract class LargeTransactionDecorator implements Account { ...} |
装饰器的装修类型实现方法,可以让他拦截他想要拦截的.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Decoratorpublic abstract class LargeTransactionDecorator implements Account { @Inject @Delegate @Any Account account; @PersistenceContext EntityManager em; public void withdraw(BigDecimal amount) { ... } public void deposit(BigDecimal amount); ... }} |
需要注意的是,一个装饰器可能是一个抽象类. 因此,某些情况下你可能不需要去实现方法.
2.Delegate object(委托对象)
decorator有特殊的注射点,称为委托注入点(delegate injection point),
其必须有一个delegate injection point,可以是一个构造函数参数,初始化方法参数或injected field.
|
1
2
3
4
5
6
|
@Decoratorpublic abstract class LargeTransactionDecorator implements Account { @Inject @Delegate @Any Account account; ...} |
像上面这段代码,装饰器将绑定到所有实现了Account的Bean上.
如果是下面这段代码,@Foreign是我们自定义.
那么装饰器将绑定到实现了Account的Bean并且qualifiers是@Foreign的Bean上.
|
1
2
3
4
5
6
|
@Decoratorpublic abstract class LargeTransactionDecorator implements Account { @Inject @Delegate @Foreign Account account; ...} |
decorator可能调用委托对象,和拦截器调用InvocationContext.proceed() 有大致有相同的结果.但主要的区别在于装饰可以委托对象上调用任何业务方法。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Decoratorpublic abstract class LargeTransactionDecorator implements Account { @Inject @Delegate @Any Account account; @PersistenceContext EntityManager em; public void withdraw(BigDecimal amount) { account.withdraw(amount); if ( amount.compareTo(LARGE_AMOUNT)>0 ) { em.persist( new LoggedWithdrawl(amount) ); } } public void deposit(BigDecimal amount); account.deposit(amount); if ( amount.compareTo(LARGE_AMOUNT)>0 ) { em.persist( new LoggedDeposit(amount) ); } }} |
3.Enabling decorators(启用装饰器)
默认情况下,所有装饰器都是禁用的.推荐用bean.xml进行开启.bean.xml是第一优先的.其次才是@Priority.
CDI 1.1以后的decorator可以使用@Priority开启。@Priority定义了装饰器和拦截器的优先顺序,但还是没bean.xml里直观.
|
1
2
3
4
5
6
7
8
9
10
11
|
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"> <decorators> <class>org.mycompany.myapp.LargeTransactionDecorator</class> </decorators></beans> |
注意:不要即在bean.xml配置又写@Priority.可能会出一些奇怪的问题.根本上,同时用这两种方式就是错误的.
CDI services--Decorators(装饰器)的更多相关文章
- CDI Services *Decoretions *Intercepters * Scope * EL\(Sp EL) *Eventmodel
1.Decorators装饰器综述 拦截器是一种强大的方法在应用程序捕捉运行方法和解耦.拦截器可以拦截任何java类型的调用. 这使得拦截器适合解决事务管理,安全性,以及日记记录. 本质上说,拦截 ...
- Python入门笔记(19):Python函数(2):函数/方法装饰器
一.装饰器(decorators) 装饰器的语法以@开头,接着是装饰器函数的名字.可选参数. 紧跟装饰器声明的是被装饰的函数和被装饰的函数的可选参数,如下: @decorator(dec_opt_ar ...
- Python全栈工程师(装饰器、模块)
ParisGabriel 每天坚持手写 一天一篇 决定坚持几年 全栈工程师 Python人工智能从入门到精通 装饰器 decorators(专业提高篇) 装饰 ...
- BehaviorTree.CPP行为树BT的装饰器节点(五)
Decorators 装饰器是只能有一个子项的节点. 由装饰者来决定是否,何时以及对子节点进行tick. InverterNode tick子节点一次,如果子节点失败则返回SUCCESS,如果孩子成功 ...
- 通过decorators = [,] 的形式给类中的所有方法添加装饰器
给类添加装饰器有多种方法: 1.可以在类中的某个方法上边直接@添加,这个粒度细.无需详细介绍 2.也可以在类中通过 decorators=[, ]的形式添加,这样的话,类中的所有方法都会被一次性加上装 ...
- TypeScript学习笔记(九):装饰器(Decorators)
装饰器简介 装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式. 需要注意的是:装饰器是一项实验性特性,在未来的版本中可能会发生改变. 若要启用实验性的装饰器特 ...
- Python装饰器(Decorators )
http://book.pythontips.com/en/latest/decorators.html 在<Built-in Functions(3.6)>和<Python上下文管 ...
- 【低门槛 手把手】python 装饰器(Decorators)原理说明
本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是,在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我们 ...
- 关于python装饰器(Decorators)最底层理解的一句话
一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...
随机推荐
- spark的bulkload报错及解决
需求 将HDFS上的数据解析出来,然后通过hfile方式批量写入Hbase(需要多列写入) 写入数据的关键api: rdd.saveAsNewAPIHadoopFile( stagingFolder, ...
- Python 实现 动态规划 /斐波那契数列
1.斐波那契数列 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数 ...
- 新世界主机_XenServer7.0都有哪些优势?
新世界主机VPS全部都采用了Xen硬件虚拟化技术,每个用户都能够独享资源,一键就可以创建和重装VPS,每个VPS都拥有足够的带宽,保证顺畅运行(http://m.0830mn.com). 新世界主机使 ...
- 20172328 2018-2019《Java软件结构与数据结构》第八周学习总结
20172328 2018-2019<Java软件结构与数据结构>第八周学习总结 概述 Generalization 本周学习了二叉树的另一种有序扩展?是什么呢?你猜对了!ヾ(◍°∇°◍) ...
- SQLServer 2014 内存优化表
内存优化表是 SQLServer 2014 的新功能,它是可以将表放在内存中,这会明显提升DML性能.关于内存优化表,更多可参考两位大侠的文章:SQL Server 2014新特性探秘(1)-内存数据 ...
- Centos7安装InfluxDB1.7
Centos7安装InfluxDB1.7 本操作参照InfluxDB官网:InfuxDB 使用的Red Hat和CentOS用户可以安装InfluxDB最新的稳定版本 yum包管理器: cat < ...
- SSH(Spring Struts2 Hibernate)框架整合(xml版)
案例描述:使用SSH整合框架实现部门的添加功能 工程: Maven 数据库:Oracle 案例架构: 1.依赖jar包pom.xml <project xmlns="http://ma ...
- [CF542A]Place Your Ad Here
[CF542A]Place Your Ad Here 题目大意: 有\(n(n\le2\times10^5)\)个广告和\(m(m\le2\times10^5)\)个电视台,第\(i\)个广告只能在\ ...
- c#常用数值范围汇总
short.MaxValue 32767 short.MinValue -32768 int.MaxValue 2147483647 int.MinValue -2147483648 long.Max ...
- 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第5章编程练习6
#include <iostream>#include <string>using namespace std;struct car{ string pro; int yea ...