Spring总结七:AOP动态代理的实现
Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类。
首先我们来用代码简单演示jdk动态代理:
现在有一个商品的增删改查的操作
/**
* 商品操作接口
*/
public interface ProductService {
public void add();
public void edit();
public void delte();
public void select();
} /**
* 实现类
*/
public class ProductServiceImpl implements ProductService {
@Override
public void add() {
System.out.println("添加商品");
} @Override
public void edit() {
System.out.println("修改商品");
} @Override
public void delte() {
System.out.println("删除商品");
} @Override
public void select() {
System.out.println("查询商品");
}
}
我们编写一个基于jdk的动态代理(实现InvocationHandler接口):
public class JdkProxy implements InvocationHandler { //被代理的目标
private Object target; //构造函数 传入目标对象
public JdkProxy(Object target) {
this.target = target;
} //提供创建代理对象的方法
public Object createProxy() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} /**
* 实现InvocationHandler接口的回调方法, 拦截目标对象所有方法都会执行invoke方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是代理,我对被代理的目标有绝对的控制权...");
Object returnVal = method.invoke(target, args);
System.out.println("--------------------------------------");
return returnVal;
}
}
测试代码:
public class JdkProxyTest {
@Test
public void testJdkProxy() {
//创建对象
ProductService target = new ProductServiceImpl();
//创建代理对象
JdkProxy jdkProxy = new JdkProxy(target);
//代理面向接口
ProductService proxy = (ProductService) jdkProxy.createProxy();
//通过代理调用方法
proxy.add();
proxy.edit();
proxy.delte();
proxy.select();
}
}
运行结果:
jdk的代理,目标必须有接口
而cglib的代理不管有没有接口都可以
下面简单说一下cglib的动态代理:
ProductService
public class ProductService {
public void add() {
System.out.println("添加商品");
} public void edit() {
System.out.println("修改商品");
} public void delte() {
System.out.println("删除商品");
} public void select() {
System.out.println("查询商品");
}
}
CglibProxy:
public class CglibProxy {
private Object target; public CglibProxy(Object target) {
this.target = target;
} public Object createProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 增强的功能
System.out.println("这么巧,我也是代理.......................");
// 原来的功能
Object returnVal = method.invoke(target, args);
return returnVal;
}
});
// 返回 代理对象(增强之后的对象)
return enhancer.create();
} }
测试代码:
public class CglibProxyTest {
@Test
public void testCglibProxy() {
ProductService target = new ProductService();
CglibProxy cglibProxy = new CglibProxy(target);
ProductService proxy = (ProductService) cglibProxy.createProxy();
proxy.add();
proxy.edit();
proxy.delte();
proxy.select();
}
}
运行结果:
其实除了动态代理,还有静态代理,以后总结设计模式的时候再详细说。设计模式之 代理模式
Spring总结七:AOP动态代理的实现的更多相关文章
- spring源码-aop动态代理-5.3
一.动态代理,这是一个很强大的东西哦.研发过程中我们会常用很多业务类,但是存在一个问题.如何在不修改源码逻辑的情况下,加入自己的相关逻辑.比如异常处理,日志记录等! 二.Java动态代理的两种方式JD ...
- Spring学习笔记之aop动态代理(3)
Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...
- Spring中的cglib动态代理
Spring中的cglib动态代理 cglib:Code Generation library, 基于ASM(java字节码操作码)的高性能代码生成包 被许多AOP框架使用 区别于JDK动态代理,cg ...
- Spring中的JDK动态代理
Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...
- Spring事务Transactional和动态代理(二)-cglib动态代理
系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...
- Spring事务Transactional和动态代理(三)-事务失效的场景
系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
- Spring事务Transactional和动态代理(一)-JDK代理实现
系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...
- Spring AOP 动态代理 缓存
Spring AOP应用:xml配置及注解实现. 动态代理:jdk.cglib.javassist 缓存应用:高速缓存提供程序ehcache,页面缓存,session缓存 项目地址:https://g ...
随机推荐
- Mongodb 的劣势
MongoDB中的数据存放具有相当的随意性,不具有MySQL在开始就定义好了.对运维人员来说,他们可能不清楚数据库内部数据的数据格式,这也会数据库的运维带来了麻烦. 1. 事务关系支持薄弱.这也是所有 ...
- 2017年--10年java大神告诉你开发最常用的百分之二十的技术有哪些?
首先题主说的20%我不知道从哪方面去理解.接下来我会将自己多年来工作中会经常使用到的技术列出来. 1.html.css 2.java工作原理(jvm) 3.java语法.数据结构和算法 4.java语 ...
- Linux 监视文件、文件夹改动
/******************************************************************** * Linux 监视文件.文件夹改动 * 说明: * 主要是 ...
- 安卓开发第一记 android stdio 安装后 新建测试项目报错
Failed to resolve:com.android.support:appcompat-v7:报错处理 你在使用android studio时是否也出现过上图的报错,你还在为它的出现烦恼? ...
- Centos7下命令笔记-ls
ls命令大概是linux下最常用的命令之一,ls是list的缩写.因为linux目录或者文件记录的信息实在太多,所以默认ls只显示非隐藏的目录以及文件名.ls直接执行不加参数时显示本目录下的档案名. ...
- 重温CLR(二)生成、部署以及程序集
将类型生成到模块中 class Program { static void Main(string[] args) { Console.WriteLine("Hi"); } } 该 ...
- 通信对象System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于“出错”状态。
问题描述:在客户端站点访问WCF服务后,在页面停留时间过长,客户端站点将会报错.报错内容如下: 通信对象System.ServiceModel.Channels.ServiceChannel 无法用于 ...
- test20181219 连续段的期望
题意 连续段的期望 [问题描述] 小N最近学习了位运算,她发现2个数xor之后数的大小可能变大也可能变小,and之后都不会变大,or之后不会变小.于是她想算出以下的期望值:现在有 N个数排成一排,如果 ...
- matlab_移动文件和复制文件
clear clc cd('C:\Users\xx\Desktop\learning'); % 设置当前目录 % 此时learning文件夹中有:文件夹x, 文件夹y, 文件a.png, 文件b.pn ...
- bzoj 2865 字符串识别——后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2865 做出 ht[ ] 之后,sa[ ] 上每个位置和它前面与后面取 LCP ,其中较大的长 ...