JAVA动态代理和方法拦截(使用CGLib实现AOP、方法拦截、委托)
AOP用CGLib更简便、更可控。
动态代理的实现非常优雅。
实体类:
public class SampleClass { public String MyFunction1(String input) { System.out.println("MyFunction1方法被调用:Hello:" + input);
return "Hello:" + input;
} public String MyFunction2(String input) { System.out.println("MyFunction2方法被调用:Hello:" + input);
return "Hello:" + input;
}
}
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Dispatcher;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.FixedValue;
import net.sf.cglib.proxy.LazyLoader;
import net.sf.cglib.proxy.NoOp;
import net.sf.cglib.proxy.ProxyRefDispatcher; public class CgLibTest { private static String MyName = ""; public static void main(String[] args) { MyName = "王昕"; DoAOP(); Enhancer enhancer1 = EnhancerNoOp();
SampleClass proxy = (SampleClass) enhancer1.create();
String strOutput = proxy.MyFunction2("赵七");
System.out.println("EnhancerNoOp:"+strOutput); Enhancer enhancer2 = EnhancerFixedValue();
SampleClass proxy2 = (SampleClass) enhancer2.create();
String strOutput2 = proxy2.MyFunction2("赵七");
System.out.println("EnhancerFixedValue:"+strOutput2); } private static void DoAOP() {
MyInterceptor cglib = new MyInterceptor();
SampleClass bookCglib = (SampleClass) cglib
.getInstance(new SampleClass());
bookCglib.MyFunction2("张三");
} // 该回调将替代原类的方法实现
private static Enhancer EnhancerFixedValue() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(new FixedValue() {
@Override
public Object loadObject() throws Exception {
//返回 MyName 作为输入参数的;
return new SampleClass().MyFunction2(MyName);
}
});
return enhancer;
} //执行原(Super)类方法
private static Enhancer EnhancerNoOp() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(NoOp.INSTANCE);
return enhancer;
} //延迟加载
private static Enhancer EnhancerLazyLoader() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(new LazyLoader() {
@Override
public Object loadObject() throws Exception {
//return "回调后的返回值";
return new SampleClass().MyFunction2(MyName);
}
});
return enhancer;
} private static Enhancer EnhancerProxyRefDispatcher(final String obj1) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class); enhancer.setCallback(new ProxyRefDispatcher() {
@Override
public Object loadObject(Object obj2) throws Exception {
return new SampleClass().MyFunction2(obj1 + (String)obj2);
}
});
return enhancer;
} }
AOP拦截模拟类:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class MyInterceptor implements MethodInterceptor {
private Object target; public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
} @Override
// 回调方法
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("拦截前,做些事情");
proxy.invokeSuper(obj, args);
System.out.println("拦截后,再做些事情");
return null; } }
输出:
拦截前,做些事情
MyFunction2方法被调用:Hello:张三
拦截后,再做些事情
MyFunction2方法被调用:Hello:赵七
EnhancerNoOp:Hello:赵七
MyFunction2方法被调用:Hello:王昕
EnhancerFixedValue:Hello:王昕
MethodDelegate
方法委托: 实现类似C#的委托。将方法调用绑定到某个接口的特定方法
public void testMethodDelegate() throws Exception {
SampleBean bean = new SampleBean();
bean.setValue("Hello cglib!");
BeanDelegate delegate = (BeanDelegate) MethodDelegate.create(bean,
"getValue", BeanDelegate.class);
assertEquals("Hello world!", delegate.getValueFromDelegate2());
} public interface BeanDelegate {
//String getValueFromDelegate1();
String getValueFromDelegate2();
}
BulkBean
使用数组访问bean的访问器方法调用
public void testBulkBean() throws Exception {
BulkBean bulkBean = BulkBean.create(SampleBean.class,
new String[] { "getValue" }, new String[] { "setValue" },
new Class[] { String.class });
SampleBean bean = new SampleBean();
bean.setValue("Hello world!");
assertEquals(1, bulkBean.getPropertyValues(bean).length);
assertEquals("Hello world!", bulkBean.getPropertyValues(bean)[0]);
bulkBean.setPropertyValues(bean, new Object[] { "Hello cglib!" });
assertEquals("Hello cglib!", bean.getValue());
}
public class SampleBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
JAVA动态代理和方法拦截(使用CGLib实现AOP、方法拦截、委托)的更多相关文章
- Java动态代理之JDK实现和CGlib实现
一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由 业务实现类.业务代理类 两部分组成.业务实现类 负责实现 ...
- Java动态代理之JDK实现和CGlib实现(简单易懂)
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6542259.html 一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是 ...
- 【转载】Java动态代理之JDK实现和CGlib实现(简单易懂)
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6542259.html 一:代理模式(静态代理) 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是 ...
- 详解Java动态代理机制(二)----cglib实现动态代理
上篇文章的结尾我们介绍了普通的jdk实现动态代理的主要不足在于:它只能代理实现了接口的类,如果一个类没有继承于任何的接口,那么就不能代理该类,原因是我们动态生成的所有代理类都必须继承Proxy这个类, ...
- java 动态代理模式(jdk和cglib)
package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...
- Java动态代理实现方式一
Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理 实现方式一:静态代理 静态代理方式的优点 静态代理方式的缺点 Java动态代理实现方式一:InvocationHandler Ja ...
- java动态代理模式
java动态代理机制详解 Spring的核心AOP的原理就是java的动态代理机制. 在java的动态代理机制中,有两个重要的类或接口: 1.InvocationHandler(Interface): ...
- Java动态代理——框架中的应用场景和基本原理
前言 之前已经用了5篇文章完整解释了java动态代理的原理,本文将会为这个系列补上最后一块拼图,展示java动态代理的使用方式和应用场景 主要分为以下4个部分 1.为什么要使用java动态代理 2.如 ...
- Java动态代理与Cglib库
JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...
- Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...
随机推荐
- 实现一套山寨springMVC
重复造轮子没有意义,但是通过现已存在的轮子,模仿着思路去实现一套,还是比较cool的.花了三天,终于深夜搞定!收益都在代码里,我干了,您随意! 一.简单思路 简单介绍: 1.所有的请求交给TyDisp ...
- UVa 11542 Square (高斯消元)
题意:给定 n 个数,从中选出一个,或者是多个,使得选出的整数的乘积是完全平方数,求一共有多少种选法,整数的素因子不大于 500. 析:从题目素因子不超过 500,就知道要把每个数进行分解.因为结果要 ...
- 安卓开机logo和开机动画的几种实现方法
安卓4.2可用方法2-4,第一种方法未验证. 从理论上来说,android 有4个开机启动画面. 第一个应该是U-BOOT的启动画面,有些设备为了满足按动电源即有显示,在UBOOT里加了开机画面,实现 ...
- canvas制作表盘
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Window下同一台服务器部署多个tomcat服务简易教程
第一步:解压两份tomact 分别为tomactserver01和tomactserver02文件夹 第二.配置tomact的环境变量 分别为 第三步:分别修改tomact的bin目录下的catali ...
- Silverlight中图片显示
silverlight中显示一个图片有很多的中方法,xaml中的image控件或者自定编写程序来生成image控件. silverlight中显示的图片只能是Bitmap, JPG, PNG(64位颜 ...
- js常见input校验
//校验输入价格等,保留2位小数 function clearNoNum(obj){ obj.onkeyup = function(event){ var e = event || window.ev ...
- 属性动画和Activity、Fragment过渡动画等
主题是关于动画的,但是不是什么动画的内容都包括.先泛泛的介绍一下,然后详细的介绍一下翻代码找见的一个好玩的动画的使用.以下的内容包括Android 3和Android 3.1等引入的API,在使用中请 ...
- spring注解开发
applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xm ...
- POJ2061 Subsequence 2017-05-25 19:49 83人阅读 评论(0) 收藏
Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14709 Accepted: 6210 Desc ...