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属性实现过滤链的更多相关文章

  1. Autofac - 方法注入

    方法注入, 其实就是在注册类的时候, 把这个方法也注册进去. 那么在生成实例的时候, 会自动调用这个方法. 其实现的方法, 有两种. 准备工作: public interface IAnimal { ...

  2. Spring应用教程-2 方法注入

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 我们通常使用lookup方法注入,它可使Spring替换一个Bean的抽象或具体方法,返回查找容器中,其他Bea ...

  3. 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值

    接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...

  4. spring setter方法注入

    <bean id="dao" class="Dao"></bean> <bean id="service" c ...

  5. Ninject依赖注入——构造函数、属性、方法和字段的注入

    Ninject依赖注入——构造函数.属性.方法和字段的注入(三) 1.Ninject简介 Ninject是基于.Net平台的依赖注入框架,它能够将应用程序分离成一个个高内聚.低耦合(loosely-c ...

  6. Spring揭秘 读书笔记 四----方法注入

    我们知道,拥有prototype类型scope的bean,在请求方每次向容器请求该类型对象的时候,容器都会返回一个全新的该对象实例. 我们看下面的例子: public class MockNewsPe ...

  7. spring依赖注入之构造函数注入,set方法注入

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  8. .NET手记-Autofac进阶(属性和方法注入 Property and Method Injection)

    尽管构造函数参数注入是传递参数值给当前构造的组件的优先方式,但是你也可以使用属性或者方法注入来提供参数值. 属性注入使用可写入的变量而不是构造函数参数来完成注入.方法注入则通过方法来设置依赖项. 属性 ...

  9. id、name、setter方法注入、构造方法注入、工厂方法注入、注解注入、方法注入、方法替换、Web作用域、普通bean引用Web作用域的bean

    spring IoC的id和name id的命名需要满足XML对id的命名规范,必须以字母开始,后面可以是字母.数字.连字符.下画线.句号.冒号等等号,但逗号和空格是非法的.如果用户确实希望用一些特殊 ...

随机推荐

  1. 自学Python2.10-跳出循环(break、continue)

    自学Python之路 自学Python2.10-跳出循环(break.continue) 1.跳出循环break, 跳出同层的循环 break语句可以跳出for和while的循环体. 如果你从for或 ...

  2. 洛谷 P2058 海港 解题报告

    P2058 海港 题目描述 小K是一个海港的海关工作人员,每天都有许多船只到达海港,船上通常有很多来自不同国家的乘客. 小K对这些到达海港的船只非常感兴趣,他按照时间记录下了到达海港的每一艘船只情况: ...

  3. 【bzoj1568】 JSOI2008—Blue Mary开公司

    http://www.lydsy.com/JudgeOnline/problem.php?id=1568 (题目链接) 题意 在线维护若干条直线,询问一些横坐标上的最高直线的纵坐标. Solution ...

  4. Linux下定时器

    http://unix8.net/linux%E4%B8%8B%E5%AE%9A%E6%97%B6%E5%99%A8.html 一. 基础知识 1.时间类型.Linux下常用的时间类型有4个:time ...

  5. POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)

    POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...

  6. (转)Redis的那些最常见面试问题

    背景:最近在准备面试相关的题目,发现redis基本一片空白,有必要好好总结下. 转自:https://www.cnblogs.com/Survivalist/p/8119891.html 1.什么是r ...

  7. 跟我一起学习vue2(学习工程目录)[三]

    查看生成的my-project的工程目录 首先看 build是最终发布的代码存放位置. 我查看了一下目录,里面都是Js文件 config目录里面主要是配置目录,包括端口号.如果开的项目多,可以进入in ...

  8. 斯坦福大学公开课机器学习:监督学习在行人检测的应用(supervised learning for pedestrian detection)

    对于下图,左边是行人,作为阳性例子,赋值y=1,右边是景物,作为阴性例子,赋值y=0; 步长概念: 如下图所示,步长表示绿色框框移动的距离,有时候也称为滑动参数stride,如果一次移动一个像素,则称 ...

  9. main方法或者junit单元测试报 类找不到异常

    MyEclipse10.7+Maven项目junit单元测试报找不到类异常,附正常编译后的输出设置   1 首先想到的是输出路径错误 一般不是maven工程的项目编译后的.class文件会在/weba ...

  10. wget一个网站很慢的原因

    今天wget一个网站时,发现很慢: # wget www.baidu.com ---- ::-- http://www.baidu.com/ Resolving www.baidu.com... 14 ...