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虚拟机读取字节码文件,取出 ...
随机推荐
- ps中为什么在图片上面添加不了文字
我们在使用PS对某些图片进行处理时,往往会添加一些文字:但有时因图片格式问题,导致添加文字是一个小黑点,无法看清,下面就为大家讲解一下具体的处理方法. 工具/原料 Photoshop CS5.图片 ...
- Idea项目如何迁移到Eclipse
CTRL + SHIFT + ALT + S键 (即File>Project Structure), 按照如图一样设置,设置完成后就可以直接导入到eclipse了
- pt-query-digest详解慢查询日志
一.简介 pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdu ...
- 2018.12.08 codeforces 939E. Maximize!(二分答案)
传送门 二分答案好题. 题意简述:要求支持动态在一个数列队尾加入一个新的数(保证数列单增),查询所有子数列的 最大值减平均值 的最大值. 然而网上一堆高人是用三分做的. 我们先考虑当前的答案有可能由什 ...
- 2018.11.24 poj2774Long Long Message(后缀数组)
传送门 实际上可以用后缀自动机秒掉 当然后缀数组也挺好写. 我们将两个字符串接在一起,为了方便中间用一个特殊字符连接. 然后对新字符串求heightheightheight数组. 求出来之后对所有满足 ...
- Maven进行install的时候报错,COMPILATION ERROR : Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.13:test (default-test) on project cmu: There are test failures.
maven进行install的时候,test类里面报错: COMPILATION ERROR : [INFO] -------------------------------------------- ...
- 1、JavaScript 基础一 (从零学习JavaScript)
1:定义:javascript是一种弱类型.动态类型.解释型的脚本语言. 弱类型:类型检查不严格,偏向于容忍隐式类型转换. 强类型:类型检查严格,偏向于不容忍隐式类型转换. 动态类型:运行的时候执行类 ...
- Keras分类问题
#-*- coding: utf-8 -*- #使用神经网络算法预测销量高低 import pandas as pd #参数初始化 inputfile = 'data/sales_data.xls' ...
- poj 1125 Stockbroker Grapevine(最短路径)
Description Stockbrokers are known to overreact to rumours. You have been contracted to develop a me ...
- 20155205《Java程序设计》实验五(网络编程与安全)实验报告
20155205 <Java程序设计>实验五(网络编程与安全)实验报告 一.实验内容及步骤 (一) 两人一组结对编程 参考http://www.cnblogs.com/rocedu/p/6 ...