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虚拟机读取字节码文件,取出 ...
随机推荐
- JavaScript函数和内置对象
一.函数 function f1(){ console.log("666"); } f1(); //调用函数 1.普通函数定义 function f1(a,b){ console. ...
- java.security.cert.CertificateException: No subject alternative names matching IP address xxx.xxx.xxx.xxx found
https与http不同的是,https加密,需要验证证书,而http不需要. 在连接的代码中加上: static { disableSslVerification(); } private stat ...
- 用模糊查询like语句时如果要查是否包含%字符串该如何写
- 2018.10.26 NOIP模拟 性感手枪(搜索)
传送门 vis[x][y]vis[x][y]vis[x][y]记录这个点是否在之前被搜过,且被搜过的坐标是什么. 然后搜索的时候记录一个循环的下标和不循环的下标就行了. 代码
- jQuery动态控制下拉列表的被选项[转]
<form id="form" action="/query!query.action"> <select> <option va ...
- 查看MySQL语句变量了多少行数据
explain MySQL语句 列如 explain SELECT * FROM 表名 WHERE id=1;
- C# String字符串
C#(静态String类) C#中提供了比较全面的字符串处理方法,很多函数都进行了封装为我们的编程工作提供了很大的便利.System.String是最常用的字符串操作类,可以帮助开发者完成绝大部分的字 ...
- C++之引用和指针
作者:tongqingliu 转载请注明出处:http://www.cnblogs.com/liutongqing/p/7050431.html C++之引用和指针 C++引用 引用的基本用法: in ...
- URAL1099. Work Scheduling(一般图匹配带花树开花算法)
1099. Work Scheduling Time limit: 0.5 second Memory limit: 64 MB There is certain amount of night gu ...
- SPRING框架中ModelAndView、Model、ModelMap区别及详细分析
转载内容:http://www.cnblogs.com/google4y/p/3421017.html 1. Model Model 是一个接口, 其实现类为ExtendedModelMap,继承了M ...