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. Redis 数据结构之dict

    上篇文章<Redis数据结构概述>中,了解了常用数据结构.我们知道Redis以高效的方式实现了多种数据结构,因此把Redis看做为数据结构服务器也未尝不可.研究Redis的数据结构和正确. ...

  2. Codeforces 628F 最大流转最小割

    感觉和昨天写了的题一模一样... 这种题也能用hall定理取check, 感觉更最小割差不多. #include<bits/stdc++.h> #define LL long long # ...

  3. css_base_note

  4. iphone手机浏览器文本框不触发输入中文的keyup事件

    问题描述:iphone手机浏览器文本框不触发输入中文的keyup事件,在输入中文之后需要点击回退按键,才会开始搜索.问题分析:iphone手机的输入法(不管是第三方还是自带)能检测到英文或者数字的ke ...

  5. mysql 查询近7天数据,缺失补0

    相信很多人的项目都有这种需求,就是查询近7天的记录,但是这7天总有那么几天是没数据的,所以缺失的只能补 0 下面的代码不知道能不能看懂,我简单的说一下思路 1)先查询红色字体的近7天,再转换成日期 2 ...

  6. HDU3072 Intelligence System

    题目传送门 有个中文版的题面...和原题稍有不同 /* Description “这一切都是命运石之门的选择.” 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短信,并由此得知了伦 ...

  7. 英语口语练习系列-C35-马戏-谈论语言-己亥杂诗

    词汇-马戏 circus audience spectator spotlight bandstand magic magician clown spacious attractive product ...

  8. XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia

    1. GUI 按题意判断即可. #include<stdio.h> #include<iostream> #include<string.h> #include&l ...

  9. MongDB增删改查

    增加 增加一条:db.th.insertOne({}) // 返回 _id 增加多条:db.th.insertMany([{},{},{}]) // 返回 _ids 针对Array增加操作: db.s ...

  10. JTS相关资料和示例

    示例 JTS基本概念和使用 JTS Geometry之间的关系 JTS algorithm package