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
@Decorator
public abstract class LargeTransactionDecorator implements Account {
   ...
}

装饰器的装修类型实现方法,可以让他拦截他想要拦截的.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Decorator
public 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
@Decorator
public abstract class LargeTransactionDecorator implements Account {
 
   @Inject @Delegate @Any Account account;
   ...
}

像上面这段代码,装饰器将绑定到所有实现了Account的Bean上.

如果是下面这段代码,@Foreign是我们自定义. 
那么装饰器将绑定到实现了Account的Bean并且qualifiers是@Foreign的Bean上.

1
2
3
4
5
6
@Decorator
public 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
@Decorator
public 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(装饰器)的更多相关文章

  1. CDI Services *Decoretions *Intercepters * Scope * EL\(Sp EL) *Eventmodel

    1.Decorators装饰器综述 拦截器是一种强大的方法在应用程序捕捉运行方法和解耦.拦截器可以拦截任何java类型的调用.  这使得拦截器适合解决事务管理,安全性,以及日记记录.  本质上说,拦截 ...

  2. Python入门笔记(19):Python函数(2):函数/方法装饰器

    一.装饰器(decorators) 装饰器的语法以@开头,接着是装饰器函数的名字.可选参数. 紧跟装饰器声明的是被装饰的函数和被装饰的函数的可选参数,如下: @decorator(dec_opt_ar ...

  3. Python全栈工程师(装饰器、模块)

    ParisGabriel                每天坚持手写  一天一篇  决定坚持几年 全栈工程师     Python人工智能从入门到精通 装饰器 decorators(专业提高篇) 装饰 ...

  4. BehaviorTree.CPP行为树BT的装饰器节点(五)

    Decorators 装饰器是只能有一个子项的节点. 由装饰者来决定是否,何时以及对子节点进行tick. InverterNode tick子节点一次,如果子节点失败则返回SUCCESS,如果孩子成功 ...

  5. 通过decorators = [,] 的形式给类中的所有方法添加装饰器

    给类添加装饰器有多种方法: 1.可以在类中的某个方法上边直接@添加,这个粒度细.无需详细介绍 2.也可以在类中通过 decorators=[, ]的形式添加,这样的话,类中的所有方法都会被一次性加上装 ...

  6. TypeScript学习笔记(九):装饰器(Decorators)

    装饰器简介 装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式. 需要注意的是:装饰器是一项实验性特性,在未来的版本中可能会发生改变. 若要启用实验性的装饰器特 ...

  7. Python装饰器(Decorators )

    http://book.pythontips.com/en/latest/decorators.html 在<Built-in Functions(3.6)>和<Python上下文管 ...

  8. 【低门槛 手把手】python 装饰器(Decorators)原理说明

    本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是,在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我们 ...

  9. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

随机推荐

  1. ionic2中使用videogular2实现m3u8文件播放

    // 安装依赖 npm i videogular2 --save npm i hls.js --save // 在index.html中引入 <script src="assets/h ...

  2. POJ 3280 Cheapest Palindrome (区间DP) 经典

    <题目链接> 题目大意: 一个由小写字母组成的字符串,给出字符的种类,以及字符串的长度,再给出添加每个字符和删除每个字符的代价,问你要使这个字符串变成回文串的最小代价. 解题分析: 一道区 ...

  3. Python基础——切片实例

    切片实例 L = list(range(100)) print(L, end=' ') [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1 ...

  4. Django——在线教育项目总结

    项目简介 在线教育平台 软件依赖: WEB框架:Django(1.11.7).Django REST framework 前端框架:Vue(2.5.16) 数据库: MySql.redis 支付平台: ...

  5. SpringMVC用到的jar包

    SpringMVC用到的jar包 自己搭建一个SpringMVC框架时需要用到相应的jar包,参考下载网址: http://repo.spring.io/release/org/springframe ...

  6. 转 InnoDB索引

    原文: http://blog.codinglabs.org/articles/theory-of-mysql-index.html InnoDB索引实现 虽然InnoDB也使用B+Tree作为索引结 ...

  7. 201771010126 王燕《面向对象程序设计(Java)》第七周实验总结

    实验七 继承附加实验 实验时间 2018-10-11 1.实验目的与要求 (1)进一步理解4个成员访问权限修饰符的用途: private--私有域或私有方法:只能在定义它的类中使用 public--公 ...

  8. python中栈的单链表实现

    参考博客:https://www.cnblogs.com/stacklike/p/8284550.html 基于列表的简单实现 # 先进后出 # 以列表实现的简单栈 class SimpleStack ...

  9. JavaScript开发者应懂的33个概念

    简介 这个项目是为了帮助开发者掌握 JavaScript 概念而创立的.它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南. 本篇文章是参照 @leonardomso 创立,英文版项 ...

  10. Python练手例子(1)

    1.有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. #本人的运行 ...