java动态代理的两种方法
动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还需要asm包。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。
第一种通过jdk的动态代理(必须接口):
主类(实现主要方法的类)接口:
- package bean;
- public interface TestInter {
- public void save();
- }
- 具体类:
- package bean;
- public class TestClass implements TestInter{
- public void save(){
- System.out.println("调用TestClass.save()");
- }
- }
代理类:
- package bean;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import org.apache.log4j.Logger;
- public class Test implements InvocationHandler {
- private Object originalObject;
- public Object bind(Object obj) {
- System.out.println("coming here...");
- this.originalObject = obj;
- return Proxy.newProxyInstance(
- obj.getClass().getClassLoader(),
- obj.getClass().getInterfaces(),this
- );
- }
- /**
- * 反射?
- */
- public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
- Object result=null;
- if(arg1.getName().startsWith("save")){
- System.out.println("start...");
- result=arg1.invoke(this.originalObject,arg2);
- System.out.println("end...");
- }
- return result;
- }
- }
测试类:
- package bean;
- public class TestMain {
- /**
- * @param args
- */
- public static void main(String[] args) {
- Test test=new Test();
- TestClass tc=new TestClass();
- try{
- ((TestInter)test.bind(tc)).save();
- }catch(Exception e){
- System.out.println(e.getMessage());
- e.printStackTrace();
- }
- }
- }
运行结果:
- coming here...
- start...
- 调用TestClass.save()
- end...
第二种方法:
主类(实现主要方法的类):
- package cglib;
- public class TestClass {
- public void save(){
- System.out.println("调用TestClass.save()");
- }
- }
拦截器类(实现功能的地方):
- package cglib;
- import java.lang.reflect.Method;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- /**
- * 实现接口MethodInterceptor
- */
- public class MyMethodInterceptor implements MethodInterceptor {
- /**
- * 拦截器,在这里实现需要的功能
- * 在这里仅仅是在执行之前打印了start 在执行之后打印了end
- */
- public Object intercept(Object arg0, Method arg1, Object[] arg2,
- MethodProxy arg3) throws Throwable {
- System.out.println("start...");
- Object result = arg3.invokeSuper(arg0,arg2);
- System.out.println("ending...");
- return result;
- }
- }
创建代理的类:
- package cglib;
- import net.sf.cglib.proxy.Enhancer;
- public class TestProxy {
- /**
- * 创建代理类
- * @param targetClass
- * @return
- */
- public Object createProxy(Class targetClass){
- Enhancer enhancer = new Enhancer();
- //设定父类???
- enhancer.setSuperclass(targetClass);
- //这里貌似是进行回调,主要的操作被放进了MyMethodInterceptor类里
- enhancer.setCallback(new MyMethodInterceptor());
- return enhancer.create();
- }
- }
测试类
- package cglib;
- public class TestMain {
- /**
- * 测试类
- * @param args
- */
- public static void main(String[] args) {
- TestClass tc=new TestClass();
- TestProxy tp=new TestProxy();
- TestClass tcp=(TestClass)tp.createProxy(tc.getClass());
- tcp.save();
- }
- }
运行结果:
- start...
- 调用TestClass.save()
- ending...
java动态代理的两种方法的更多相关文章
- Java动态代理的两种实现方法
注:文章转载自:https://blog.csdn.net/m0_38039437/article/details/77970633 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术, ...
- Java动态代理的两种实现方式:
方式一:传统的代理 package cn.hc.domain; import java.lang.reflect.InvocationHandler; import java.lang.reflect ...
- 动态代理的两种实现方式(JDK/Cglib)
=========================================== 原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处! ================== ...
- 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)
Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC 目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
软件152 尹以操 首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml ...
- Java 创建线程的两种方法
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- 【java基础 13】两种方法判断hashmap中是否形成环形链表
导读:额,我介绍的这两种方法,有点蠢啊,小打小闹的那种,后来我查了查资料,别人都起了好高大上的名字,不过,本篇博客,我还是用何下下的风格来写.两种方法,一种是丢手绢法,另外一种,是迷路法. 这两种方法 ...
- 实验04——java保留小数的两种方法、字符串转数值
package cn.tedu.demo; import java.text.DecimalFormat; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ ...
- java动态代理的2种实现方式
java的动态代理在接java的api上有说明,这里就不写了.我理解的代理: 对特定接口中特定方法的功能进行扩展,这就是代理.代理是通过代理实例关联的调用处理程序对象调用方法. 下面通过一个例子看一下 ...
随机推荐
- photoshop 去掉gif水印
先贴上未去除水印的GIF图片!~ 打开选中需要处理的“gif文件” 下面就以动图给大家介绍一下: 首先勾选 时间轴和图层 第二步(选择区域) 第三步(选择水印区域),选择完了以后按Enter 选中第一 ...
- Linux高性能server编程——多线程编程(下)
多线程编程 条件变量 假设说相互排斥锁是用于同步线程对共享数据的訪问的话.那么条件变量则是用于线程之间同步共享数据的值. 条件变量提供了一种线程间的通信机制:当某个共享数据达到某个值得时候,唤醒等待这 ...
- this词法
1.示例代码 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UT ...
- SCSS 实用知识汇总
1.变量声明 $nav-color: #F90; nav { //$width 变量的作用域仅限于{}内 $width: 100px; width: $width; color: $nav-color ...
- JVM中类的卸载机制
类的生命周期 当Sample类被载入.连接和初始化后,它的生命周期就開始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就会结束生命周期.Sample类在方法区内的数 ...
- jgGrid获得的id值是主键的id而不是jqGrid的行号值
{name:'cityId',index:'cityId',sorttype:'int',width:0,hidden:true,key:true}, 一定要将你的主键值的的key设置为true,这样 ...
- SoapUI 测试接口演示
SoapUI 测试接口演示 CreateTime--2018年4月2日15:54:05 Author:Marydon 以webservice为例 1.安装: SoapUI-x64-5.4.0-E ...
- 【Linux】数组与关联数组
数组 数组的定义: variable=(arg1 arg2 arg3 -) 中间用空格分开,数组的下标从0开始 1.获取下标为n的元素 variable[n] 不存在数组溢出的情况,如果下标n> ...
- iOS-高仿通讯录之商品索引排序搜索
概述 TableView添加右侧索引, 将数据按照索引分组排序, 并添加搜索功能且在搜索界面复用当前页面. 详细 代码下载:http://www.demodashi.com/demo/10696.ht ...
- hdu 4031(树状数组+辅助数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4031 Attack Time Limit: 5000/3000 MS (Java/Others) ...