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虚拟机读取字节码文件,取出 ...
随机推荐
- MVC 开发模式
1.M:Model 模型:实体类和业务和dao 2.V:view 视图:JSP 3.C:Controller 控制器:servlet 3.1 作用:视图和逻辑分离 4.MVC适用场景:大型项目开 ...
- 前端之javascript的DOM对象和标签
一 DOM对象介绍 什么是HTML DOM 1.1 HTML Document Object Model(文档对象模型) 1.2 HTML DOM 定义了访问和操作HTML文档的标准方法. 1.3 H ...
- web-Amazon
一 准备实验数据 1.1.下载数据 wget http://snap.stanford.edu/data/amazon/all.txt.gz 1.2.数据分析 1.2.1.数据格式 product/p ...
- css扩大超链接的点击范围
给a标签设置display:block后,它会根据盒模型计算a标签的实际大小.这时候,你可以使用hover伪类使a的整个盒模型生效..link a{display:block;padding:2px ...
- hdu-1042(大数+万进制)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1042 参考文章:https://blog.csdn.net/tigerisland45/article ...
- Tomcat架构解析(二)-----Connector、Tomcat启动过程以及Server的创建过程
Connector用于跟客户端建立连接,获取客户端的Socket,交由Container处理.需要解决的问题有监听.协议以及处理器映射等等. 一.Connector设计 Connector要实现的 ...
- Codeforces 1060E(思维+贡献法)
https://codeforces.com/contest/1060/problem/E 题意 给一颗树,在原始的图中假如两个点连向同一个点,这两个点之间就可以连一条边,定义两点之间的长度为两点之间 ...
- GDI基础(3):绘制图片
1.CBitmap位图类封装了Windows GDI中的位图和操作位图的成员函数.CPen.CBrush.CFont.CBitmap是常用的Windows GDI对象,和CFont一样,CBitmap ...
- arguments[0]()的详解
var length = 10; function fn(){ console.log(this.length); } var obj = { length:5, method:function(fn ...
- urb的处理流程
USB分析 2013年11月11日 16:06:24 阅读数:1807 转载自:http://blog.csdn.net/aaa6695798/article/details/4776202 很久 ...