Java编程之动态代理
来源:互联网 发布:卷皮和淘宝质量哪个好 编辑:程序博客网 时间:2024/06/06 02:48
代理:在实例的方法执行之前,由代理插入一段执行代码,然后调用实例的方法,之后也可以插入一段代码。这是AOP编程的核心。
在Java中实现动态代理有两种方式:
★ JDK动态代理 – 应用于代理实现了接口的类
★ cglib动态代理 – 主要应用于代理普通类(未实现接口)
先说说JDK动态代理
JDK动态代理主要依靠JavaAPI中的Proxy
类,这个类中有个重要的方法
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.
这是这个方法的英文解释,供参考。
对上面的方法做个理解:
▷ ClassLoader loader
类加载器,加载被代理类的字节码。
▷ Class<?>[] interfaces
被代理类实现的接口,代理类要和被代理类有相同的行为
▷ InvocationHandler h
指定如何代理, 用到策略设计模式
案例一
//接口public interface Human { void sing(float money); void dance(float money);}
//实现类public class SpringBrother implements Human { public void sing(float money) { System.out.println("拿到:"+money+" 元开始唱歌"); } public void dance(float money) { System.out.println("拿到:"+money+" 元开始跳舞"); }}
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class Client1 { public static void main(String[] args) { final Human sb = new SpringBrother(); //产生代理类,得到他的实例 Human proxyMan = (Human)Proxy.newProxyInstance(sb.getClass().getClassLoader(), sb.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("sing".equals(method.getName())){ //唱歌 float money = (Float)args[0]; if(money>10000){ method.invoke(sb, money/2); } } if("dance".equals(method.getName())){ //唱歌 float money = (Float)args[0]; if(money>20000){ method.invoke(sb, money/2); } } return null; } } ); proxyMan.sing(20000); proxyMan.dance(100000); }}
运行结果:
拿到钱:10000.0开唱 拿到钱:50000.0开跳
InvocationHandler是调用处理程序,每个代理类都对应一个调用处理程序
它是个接口,里面只有一个invoke()方法,每个类对其都有不同的实现,用到了策略设计模式
Object invoke(Object proxy, Method method, Object[] args)
● Object proxy
对被代理对象的引用。
● Method method
调用了被代理对象的哪个方法
● Object[] args
当前方法用到的参数,没有则为null
再一个就是cglib动态代理
案例二
public class SpringBrother{ public void sing(float money) { System.out.println("拿到:"+money+" 元开唱"); } public void dance(float money) { System.out.println("拿到:"+money+"元开跳"); }}
import java.lang.reflect.Method;import net.sf.cglib.proxy.Callback;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class Client1 { public static void main(String[] args) { final SpringBrother sb = new SpringBrother(); /* Class type:代理类的父类型 Callback cb:回调,如何代理 */ SpringBrother proxy = (SpringBrother) Enhancer.create(SpringBrother.class,new MethodInterceptor(){ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable { //判断出场费 if("sing".equals(method.getName())){ //唱歌 float money = (Float)args[0]; if(money>10000){ method.invoke(sb, money/2); } } if("dance".equals(method.getName())){ //唱歌 float money = (Float)args[0]; if(money>20000){ method.invoke(sb, money/2); } } return null; } }); System.out.println(proxy instanceof SpringBrother); proxy.dance(100000); proxy.sing(50000); }}
运行结果:
拿到钱:50000.0 元开跳 拿到:25000.0 元开唱
参考有关动态代理的原理了解底层原理
- Java编程之动态代理
- JAVA AOP编程之动态代理技术
- Java动态代理之JDK动态代理和CGLib动态代理 面向切面编程AOP原理
- Java 代理之 动态代理
- java之动态代理
- java之动态代理
- Java之动态代理
- java之动态代理
- java之动态代理
- java之动态代理
- Java之动态代理
- Java之动态代理
- java之动态代理
- java之动态代理
- java之动态代理
- Java动态代理之JDK动态代理
- java技术之动态代理以及AOP编程
- 【JAVA】代理模式之Java动态代理
- Maven—项目管理工具
- 每天一个Linux命令(58):wget
- JSESSIONID、SESSION、cookie .
- [Leetcode] 94. Binary Tree Inorder Traversal 解题报告
- angular2国际化插件
- Java编程之动态代理
- docker export和save的异同
- 代理有风险 设置需注意
- JS-Table动态增加删除行
- Docker战略结盟Rancher,提供企业级落地技术支持
- C#高效绘图(转)
- Abstract Factory(抽象工厂模式)
- android Sqlite expert中使用SQL 语句插入两条记录
- 在Linux下如何运行.sh文件