使用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的命名规范,必须以字母开始,后面可以是字母.数字.连字符.下画线.句号.冒号等等号,但逗号和空格是非法的.如果用户确实希望用一些特殊 ...
随机推荐
- 自学Python2.10-跳出循环(break、continue)
自学Python之路 自学Python2.10-跳出循环(break.continue) 1.跳出循环break, 跳出同层的循环 break语句可以跳出for和while的循环体. 如果你从for或 ...
- 洛谷 P2058 海港 解题报告
P2058 海港 题目描述 小K是一个海港的海关工作人员,每天都有许多船只到达海港,船上通常有很多来自不同国家的乘客. 小K对这些到达海港的船只非常感兴趣,他按照时间记录下了到达海港的每一艘船只情况: ...
- 【bzoj1568】 JSOI2008—Blue Mary开公司
http://www.lydsy.com/JudgeOnline/problem.php?id=1568 (题目链接) 题意 在线维护若干条直线,询问一些横坐标上的最高直线的纵坐标. Solution ...
- Linux下定时器
http://unix8.net/linux%E4%B8%8B%E5%AE%9A%E6%97%B6%E5%99%A8.html 一. 基础知识 1.时间类型.Linux下常用的时间类型有4个:time ...
- POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)
POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...
- (转)Redis的那些最常见面试问题
背景:最近在准备面试相关的题目,发现redis基本一片空白,有必要好好总结下. 转自:https://www.cnblogs.com/Survivalist/p/8119891.html 1.什么是r ...
- 跟我一起学习vue2(学习工程目录)[三]
查看生成的my-project的工程目录 首先看 build是最终发布的代码存放位置. 我查看了一下目录,里面都是Js文件 config目录里面主要是配置目录,包括端口号.如果开的项目多,可以进入in ...
- 斯坦福大学公开课机器学习:监督学习在行人检测的应用(supervised learning for pedestrian detection)
对于下图,左边是行人,作为阳性例子,赋值y=1,右边是景物,作为阴性例子,赋值y=0; 步长概念: 如下图所示,步长表示绿色框框移动的距离,有时候也称为滑动参数stride,如果一次移动一个像素,则称 ...
- main方法或者junit单元测试报 类找不到异常
MyEclipse10.7+Maven项目junit单元测试报找不到类异常,附正常编译后的输出设置 1 首先想到的是输出路径错误 一般不是maven工程的项目编译后的.class文件会在/weba ...
- wget一个网站很慢的原因
今天wget一个网站时,发现很慢: # wget www.baidu.com ---- ::-- http://www.baidu.com/ Resolving www.baidu.com... 14 ...