使用Groovy的mixin方法注入,和mixedIn属性实现过滤链
mixin方法注入不多说,这里只是用这个属性搞一个过滤器链的功能
假设我现在有个方法,输入一个字符串,然后需求提出需要进行大写转换输出,
过了一天又要加个前缀,再过了一天,需要把一些字符过滤掉......一直修改代码肯定是最low的,所以可以利用mixedIn属性,
设计一个过滤链,加需求,只需要新增一个过滤器就行了!
目标实例:
class StringWriter extends MyWriter {
@Override
void write(String message) {
println message
}
}
主要实现字符串打印
注入的过滤器,我这里只设计两个:
转大写:
class UpperCaseFilter {
void write(String message){
def upperCase = message.toUpperCase()
//将转换后的消息传递给下一个mixin链条
def clazz = this.getClass()
//遍历mixin的链表,找到当前mixin的前一个
/**
* mixedIn: groovy提供的一个属性,为实例保存有序的mixin注入类链表
*/
for(mixin in mixedIn.mixinClasses){
//会按添加顺序从前往后开始遍历,如果实例不是当前实例,那么就继续
//直到找到当前实例时,执行的clazz是前一个mixin,最后一个mixin的是目标实例
if(mixin.mixinClass.theClass==metaClass.delegate.theClass) break
clazz=mixin.mixinClass.theClass //一直赋值,break时,clazz刚好是当前实例的前一个
}
//如果当前实例在mixin中,执行当前实例方法,否则执行目标实例方法
mixedIn[clazz].write(upperCase)
}
}
加前缀:
class PrefixFilter {
void write(String message){
message="prefix-----:"+message
def clazz = this.getClass()
//遍历mixin的链表,找到当前mixin的前一个
for(mixin in mixedIn.mixinClasses){
if(mixin.mixinClass.theClass==metaClass.delegate.theClass) break
clazz=mixin.mixinClass.theClass
}
mixedIn[clazz].write(message)
}
}
可以把遍历调用这块抽取出来或者注入到object更好,我这里懒就不弄了,主要是熟悉这个设计
方法测试:
def sendMessage(MyWriter write){
write.write("this is groovy")
}
//创建添加过滤器的writer实例
def creeateInstance(MyWriter writer,Object[] filters =[]){
//将过滤器注入到writer实例的mixin中
filters.each {filter-> writer.metaClass.mixin filter}
writer
}
//当注入多个同名同参方法时,最后加入mixin中的方法会自动隐藏掉前面的方法
// 所以默认前面的不会执行,只会执行最后一个
/**
* 这里需要按照需求控制顺序,因为过滤器会按照顺序严格执行,比如,是先加前缀还是先转大写
*/
sendMessage(creeateInstance(new StringWriter(),PrefixFilter,UpperCaseFilter))
sendMessage(creeateInstance(new StringWriter(),UpperCaseFilter,PrefixFilter))
结果,顺序不同,结果不同:

加需要的时候,只需要加个filter注入到StringWriter中就可以了!!!
使用Groovy的mixin方法注入,和mixedIn属性实现过滤链的更多相关文章
- Autofac - 方法注入
方法注入, 其实就是在注册类的时候, 把这个方法也注册进去. 那么在生成实例的时候, 会自动调用这个方法. 其实现的方法, 有两种. 准备工作: public interface IAnimal { ...
- Spring应用教程-2 方法注入
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 我们通常使用lookup方法注入,它可使Spring替换一个Bean的抽象或具体方法,返回查找容器中,其他Bea ...
- 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值
接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...
- spring setter方法注入
<bean id="dao" class="Dao"></bean> <bean id="service" c ...
- Ninject依赖注入——构造函数、属性、方法和字段的注入
Ninject依赖注入——构造函数.属性.方法和字段的注入(三) 1.Ninject简介 Ninject是基于.Net平台的依赖注入框架,它能够将应用程序分离成一个个高内聚.低耦合(loosely-c ...
- Spring揭秘 读书笔记 四----方法注入
我们知道,拥有prototype类型scope的bean,在请求方每次向容器请求该类型对象的时候,容器都会返回一个全新的该对象实例. 我们看下面的例子: public class MockNewsPe ...
- spring依赖注入之构造函数注入,set方法注入
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- .NET手记-Autofac进阶(属性和方法注入 Property and Method Injection)
尽管构造函数参数注入是传递参数值给当前构造的组件的优先方式,但是你也可以使用属性或者方法注入来提供参数值. 属性注入使用可写入的变量而不是构造函数参数来完成注入.方法注入则通过方法来设置依赖项. 属性 ...
- id、name、setter方法注入、构造方法注入、工厂方法注入、注解注入、方法注入、方法替换、Web作用域、普通bean引用Web作用域的bean
spring IoC的id和name id的命名需要满足XML对id的命名规范,必须以字母开始,后面可以是字母.数字.连字符.下画线.句号.冒号等等号,但逗号和空格是非法的.如果用户确实希望用一些特殊 ...
随机推荐
- Java递归删除目录下所有的txt文件
public static void delAllFile(File path) { if (!path.exists() || !path.isDirectory()) { //不是目录 retur ...
- day9 集合基础命令
集合的创建 s = set("hello") print(s) s = set({","alex","sb"}) print(s) ...
- 【 Gym - 101138K 】 The World of Trains (DP)
BUPT2017 wintertraining(15) #4E Gym - 101138K 题意 N节车厢的火车,每节车厢容量是1~K,那么有\(K^N\)种火车. 求选择D个连续的且容量相同的车厢的 ...
- BZOJ 2159: Crash 的文明世界(树形dp+第二类斯特林数+组合数)
题意 给定一棵 \(n\) 个点的树和一个常数 \(k\) , 对于每个 \(i\) , 求 \[\displaystyle S(i) = \sum _{j=1} ^ {n} \mathrm{dist ...
- 架构师成长之路2.4-Kickstart文件剖析
点击返回架构师成长之路 架构师成长之路2.4-Kickstart文件剖析 kickstart文件是一个简单的文本文件,它包含了一个项目列表,每个项目由一个关键字来识别. 创建kickstart文件注意 ...
- 博主自传——蒟蒻的OI之路
博主来自河北石家庄市第二中学,现在读高二,主攻信息学竞赛(其实并没有学习其他学科竞赛). NOIP中人品大爆发,使劲挤进河北省一等奖队伍,侥幸留在竞赛团队中(差点就淘汰出局啦). 关于我的ID,YOU ...
- Shell基础知识(四)
字符串详解 字符串可以由 单引号/双引号/无引号 包围.如下所示 >> str1=hello str2="hello" str3='hello' << 三种 ...
- 2018 省选 D1T2 IIIDX
题目大意: 给出k.n个数选择一种字典序最大的排列,使得对于任意的i,di>=d[i/k](下取整 下同) 分析: 很容易想到的是建树,将i的父亲设为[i/k],之后建有向边. 60分贪心: 将 ...
- vue实现添加与删除图书
先放大图,当我们点击删除的时候,图书名单就会被我们删掉.当我们重新添加回来或者添加新书的时候,我们只需要在添加新书这里添加即可. 当我点击删除的时候,只需要的就是除却删除的那一个书籍之后剩下的图书. ...
- pow log 与 (int)
1.不能用%d输出double类型的数 double a1=5.3; double a2=1234.1234; double a3=3412341.12341234; double b1=1.5; d ...