java中动态代理的实现
发布时间 - 2026-01-10 22:18:18 点击率:次动态代理的实现

使用的模式:代理模式。
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。类似租房的中介。
两种动态代理:
(1)jdk动态代理,jdk动态代理是由Java内部的反射机制来实现的,目标类基于统一的接口(InvocationHandler)
(2)cglib动态代理,cglib动态代理底层则是借助asm来实现的,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。
主要应用的框架:
Spring中的AOP,Struts2中的拦截器
具体实现:
1、定义接口和实现类
package com.example.service;
public interface UserService {
public String getName(int id);
public Integer getAge(int id);
}
package com.example.service.impl;
import com.example.service.UserService;
public class UserServiceImpl implements UserService {
public String getName(int id) {
System.out.println("------getName------");
return "cat";
}
public Integer getAge(int id) {
System.out.println("------getAge------");
return 10;
}
}
2、jdk动态代理实现
package com.example.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
/**
* 绑定委托对象并返回一个代理类
*
* @param target
* @return
*/
public Object bind(Object target) {
this.target = target;
//取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this); //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("getName".equals(method.getName())) {
System.out.println("------before " + method.getName() + "------");
Object result = method.invoke(target, args);
System.out.println("------after " + method.getName() + "------");
return result;
} else {
Object result = method.invoke(target, args);
return result;
}
}
}
package com.example.jdk;
import com.example.service.UserService;
import com.example.service.impl.UserServiceImpl;
/**
* 测试类
*/
public class RunJDK {
public static void main(String[] args) {
MyInvocationHandler proxy = new MyInvocationHandler();
UserService userServiceProxy = (UserService) proxy.bind(new UserServiceImpl());
System.out.println(userServiceProxy.getName(1));
System.out.println(userServiceProxy.getAge(1));
}
}
运行结果:
------before getName------
------getName------
------after getName------
cat
------getAge------
10
3、cglib动态代理实现:
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
CGLIB的核心类:
net.sf.cglib.proxy.Enhancer – 主要的增强类
net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现
net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用。
net.sf.cglib.proxy.MethodInterceptor接口是最通用的回调(callback)类型,它经常被基于代理的AOP用来实现拦截(intercept)方法的调用。这个接口只定义了一个方法
public Object intercept(Object object, java.lang.reflect.Method method,
Object[] args, MethodProxy proxy) throws Throwable;
第一个参数是代理对像,第二和第三个参数分别是拦截的方法和方法的参数。原来的方法可能通过使用java.lang.reflect.Method对象的一般反射调用,或者使用 net.sf.cglib.proxy.MethodProxy对象调用。net.sf.cglib.proxy.MethodProxy通常被首选使用,因为它更快。
package com.example.cglib;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLIBProxy implements MethodInterceptor {
private Object target;
/**
* 创建代理对象
*
* @param target
* @return
*/
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 o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
System.out.println(method.getName());
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("++++++after " + methodProxy.getSuperName() + "++++++");
return result;
}
}
package com.example.cglib;
import com.example.service.UserService;
import com.example.service.impl.UserServiceImpl;
/**
* 测试CGLIB
*/
public class RunCGLIB {
public static void main(String[] args) {
CGLIBProxy cglibProxy = new CGLIBProxy();
UserService userService = (UserService) cglibProxy.getInstance(new UserServiceImpl());
userService.getName(1);
userService.getAge(1);
}
}
运行结果:
++++++before CGLIB$getName$0++++++
getName
------getName------
++++++after CGLIB$getName$0++++++
++++++before CGLIB$getAge$1++++++
getAge
------getAge------
++++++after CGLIB$getAge$1++++++
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# java
# 动态代理
# JDK动态代理
# 代理接口没有实现类
# 实现动态代理方式
# 深入讲解基于JDK的动态代理机制
# JDK动态代理原理:只能代理接口
# 不能代理类问题
# 来实现
# 绑定
# 回调
# 的是
# 这一
# 第一个
# 子类
# 是由
# 则是
# 两种
# 他对
# 它是
# 这是一个
# 更有
# 就不能
# 为其
# 更快
# 因为它
# 第三个
# 第三方
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在IIS中新建站点并配置端口与物理路径?
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤
浅谈javascript alert和confirm的美化
如何制作一个表白网站视频,关于勇敢表白的小标题?
公司网站制作需要多少钱,找人做公司网站需要多少钱?
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】
如何在新浪SAE免费搭建个人博客?
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
如何获取免费开源的自助建站系统源码?
EditPlus 正则表达式 实战(3)
在线制作视频网站免费,都有哪些好的动漫网站?
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
JavaScript数据类型有哪些_如何准确判断一个变量的类型
Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
如何在云指建站中生成FTP站点?
HTML 中如何正确使用模板变量为元素的 name 属性赋值
Laravel观察者模式如何使用_Laravel Model Observer配置
Python结构化数据采集_字段抽取解析【教程】
如何在搬瓦工VPS快速搭建网站?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
在centOS 7安装mysql 5.7的详细教程
iOS UIView常见属性方法小结
作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
移动端脚本框架Hammer.js
韩国服务器如何优化跨境访问实现高效连接?
大连网站制作公司哪家好一点,大连买房网站哪个好?
如何快速搭建高效简练网站?
如何快速登录WAP自助建站平台?
如何获取PHP WAP自助建站系统源码?
网站建设整体流程解析,建站其实很容易!
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
如何快速生成高效建站系统源代码?
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
如何用IIS7快速搭建并优化网站站点?
Laravel中的Facade(门面)到底是什么原理
javascript中闭包概念与用法深入理解
Laravel怎么在Controller之外的地方验证数据
Android GridView 滑动条设置一直显示状态(推荐)
如何在腾讯云服务器上快速搭建个人网站?
详解阿里云nginx服务器多站点的配置

