知识大全 CGLib实现变化字段探测的供能
Posted 知
篇首语:树高千尺有根,水流万里有源。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 CGLib实现变化字段探测的供能相关的知识,希望对你有一定的参考价值。
CGLib实现变化字段探测的供能 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
为了巩固 CGLib 的知识 下面我们实现一个稍微复杂一点的例子
例 请实现一个拦截器 使其能够检测一个 JavaBean 的哪些字段改变了
( )首先定义一个 JavaBean
public class PersonInfo
private String name;
private String email;
private int age;
private String address;
public String getEmail()
return email;
public void setEmail(String email)
this email = email;
public String getName()
return name;
public void setName(String name)
this name = name;
public String getAddress()
return address;
public void setAddress(String address)
this address = address;
public int getAge()
return age;
public void setAge(int age)
this age = age;
( )定义一个 MethodInterceptor 这一步是最关键的
import java lang reflect Method;
import java util Collections;
import java util HashSet;
import java util Set;
import net sf cglib proxy MethodInterceptor;
import net sf cglib proxy MethodProxy;
public class JavaBeanDataChangeInterceptor implements MethodInterceptor
private static final String SET = set ;
private Set changedPropSet;
public JavaBeanDataChangeInterceptor()
changedPropSet = new HashSet();
public Object intercept(Object obj Method method Object[] args
MethodProxy proxy) throws Throwable
String name = method getName();
if (name startsWith(SET))
String s = name substring(SET length());
changedPropSet add(s);
return proxy invokeSuper(obj args);
public Set getChangedPropSet()
return Collections unmodifiableSet(changedPropSet);
public void reset()
changedPropSet clear();
定义一个集合 changedPropSet 用来存放修改了的字段名 增加了一个方法 reset 用来清空此集合 增加了一个 getChangedPropSet 方法用来供外界得到修改了的字段 为了防止调用者对 changedPropSet 做修改 因此我们采用 Collections unmodifiableSet 对返回的集合进行不可修改的修饰
在 intercept 方法中 我们判断如果被调用的方法以 set 开头 则把此字段名放入 changedPropSet 集合中
( )定义剖析用工具类
import net sf cglib proxy Callback;
import net sf cglib proxy Factory;
public class JavaBeanInterceptorUtils
public static JavaBeanDataChangeInterceptor getInterceptor(
Object obj)
if (!(obj instanceof Factory))
return null;
Factory f = (Factory) obj;
Callback[] callBacks = f getCallbacks();
for (int i = n = callBacks length; i < n; i++)
Callback callBack = callBacks[i];
if (callBack instanceof JavaBeanDataChangeInterceptor)
return (JavaBeanDataChangeInterceptor) callBack;
return null;
这个 JavaBeanInterceptorUtils 只有一个方法 getInterceptor 这个方法用于从一个被 CGLib 代理的 JavaBean 中取出拦截器 JavaBeanDataChangeInterceptor
前边提到了 CGLib 实现拦截的方式就是生成被拦截类的子类 这个子类实现了 net sf cglib proxy Factory 接口 这个接口中有一个非常重要的方法 getCallbacks() 通过这个方法我们可以得到所有的拦截器
( ) 主程序
public class MainApp
public static void main(String[] args)
Enhancer enhancer = new Enhancer();
enhancer setSuperclass(PersonInfo class);
enhancer setCallback(new JavaBeanDataChangeInterceptor());
PersonInfo info = (PersonInfo) enhancer create();
// 对生成的 JavaBean 做一些初始化
info setAddress( 地址 );
info setAge( );
info setName( tom );
// 得到拦截器
JavaBeanDataChangeInterceptor interceptor = JavaBeanInterceptorUtils
getInterceptor(info);
// 复位修改字段记录集合
interceptor reset();
// 对 JavaBean 做一些修改
editPersonInf(info);
// 得到修改了的字段
Iterator it = interceptor getChangedPropSet(erator();
while (it hasNext())
System out println(it next());
private static void editPersonInf(PersonInfo info)
info setName( Jim );
info setAddress( N Y Street );
运行结果
Address
Name
这个 变化字段拦截器 是有一定实际意义的 比如可以用来实现 只保存修改了的字段以提高效率 等功能
相关参考