springAOP之代理
AOP是指面向切面编程。
在学习AOP之前先来了解一下代理,因为传说中的AOP其实也对代理的一种应用。
首先来看这样一段代码:
public interface Hello {
void say(String name);
}
实现类:
public class HelloImpl implements Hello { public void say(String name) {
System.out.println("Hello!"+name);
}
}
如果现在需要在say调用的前后做一些操作,那最简单的方法就是直接在say方面中增加代码,但这样肯定不够优雅。
这时候可以用第一种代理模式:静态代理
public class HelloProxy implements Hello { private Hello hello; public HelloProxy(){ hello=new HelloImpl(); } public void say(String name) {
before();
hello.say(name);
after();
} private void before(){
System.out.println("before");
} private void after(){
System.out.println("after");
}
}
这样我们在保留原来HelloImple中say方法的同时,用HelloProxy代理在say方法的前后增加了before和after
调用一下试试:
public static void main(String[] args){
Hello helloProxy=new HelloProxy();
helloProxy.say("Gary");
}
运行结果:
那么新的问题来了,如果每次都需要写一个代理类不也很麻烦吗,项目中就会有很多个xxxProxy,因此就出现了 JDK动态代理。
代码如下:
public class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target){
this.target=target;
} public <T> T getProxy(){
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result=method.invoke(target,args);
after();
return result;
} private void before(){
System.out.println("before");
} private void after(){
System.out.println("after");
}
}
注:Proxy.newProxyInstance()参数有三个:
- ClassLoader
- 该实现类的所有接口
- 动态代理对象
在该类中target就是被代理的对象,该类实现了InvocationHandler接口,通过反射去动态创建Hello接口的代理类
那么现在的调用就变简单了:
public static void main(String[] args){
DynamicProxy dynamicProxy=new DynamicProxy(new HelloImpl());
Hello helloProxy= dynamicProxy.getProxy();
helloProxy.say("gary");
}
用了JDK动态代理后,我们觉得还是有问题,如果要代理一个没有接口的类,该怎么办呢,于是就轮到我们的 CGlib动态代理 出场了。
在Spring、Hibernate等框架中都用到了CGlib动态代理,maven资源如下:
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.6</version>
</dependency>
他的使用需要实现MethodInterceptor类,并完成intercept方法。CGlib 提供的是方法级别的代理:
public class CGLibProxy implements MethodInterceptor { public <T> T getProxy(Class<T> cls){
return (T) Enhancer.create(cls,this);
} public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object result=methodProxy.invokeSuper(o,objects);
after();
return result;
} private void before(){
System.out.println("before");
} private void after(){
System.out.println("after");
}
}
这样使用时就不需要提供接口了:
public static void main(String[] args){
CGLibProxy cgLibProxy= new CGLibProxy();
Hello hello=cgLibProxy.getProxy(HelloImpl.class);
hello.say("Gary");
}
最后再改造一下,加上单例模式就更完美了
private static CGLibProxy instance=new CGLibProxy(); private CGLibProxy(){
}
public static CGLibProxy getInstance(){
return instance;
}
调用就改为:
public static void main(String[] args){
Hello hello=CGLibProxy.getInstance().getProxy(HelloImpl.class);
hello.say("Gary");
}
springAOP之代理的更多相关文章
- springAOP之代理模式
springAOP指的是在spring中的AOP,什么是AOP,相对于java中的面向对象(oop),在面向对象中一些公共的行为,像日志记录,权限验证等如果都使用面向对象来做,会在每个业务方法中都写上 ...
- 深入理解SpringAOP之代理对象
本篇文章主要带大家简单分析一下AOP的代理对象,至于AOP是什么,如何配置等基础性知识,不在这里讨论.阅读前请先参考:代理模式,在这之前我们需要了解springframework的三个核心接口与get ...
- Spring知识点总结(四)之SpringAOP基础 - 代理设计模式
1. 分析程序中存在的问题(高内聚,低耦合) 通过springIOC DI) 以及注解的使用,成功解决了在程序中层与层之间出现的耦合的问题,但是在很多地方仍然存在非该层应该实现的 ...
- spring-AOP动态代理,以及aspectJ的xml配置或注解配置方法,各个拦截器的使用顺序
package com.itheima.aspect; public class MyAspect { public void check_Permissions(){ System.out.prin ...
- Spring-AOP动态代理技术(底层代码)
1.JDK代理:基于接口的动态代理技术 目标对象必须有接口,目标对象有什么方法,目标接口就有什么方法, 运行期间基于接口动态生成代理对象,所以代理对象也就有目标对象同样的方法. 注意:以下代码只是底层 ...
- SpringAOP和AspectJ
SpringAOP和AspectJ的关系 问题:之前对 SpringAOP和AspectJ的关系感到疑惑,因为曾经在书上看过SpringAOP集成了AspectJ,那么SpringAOP是直接使用了A ...
- 完整剖析SpringAOP的自调用
摘要 spring全家桶帮助java web开发者节省了很多开发量,提升了效率.但是因为屏蔽了很多细节,导致很多开发者只知其然,不知其所以然,本文就是分析下使用spring的一些注解,不能够自调用的问 ...
- Spring源码系列(三)--spring-aop的基础组件、架构和使用
简介 前面已经讲完 spring-bean( 详见Spring ),这篇博客开始攻克 Spring 的另一个重要模块--spring-aop. spring-aop 可以实现动态代理(底层是使用 JD ...
- Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现
上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...
随机推荐
- 四大组件之Activity小结
一大波面试就要靠近,赶紧总结总结一些基础问题 1.Activity的概念 是Android应用层开发的四大组件之一,主要负责和用户交互部分,有自己的生命周期,在其上可以布置按钮,文本框等各种控件,简单 ...
- polaris: session和middleware的支持
起因 polaris虽然是模仿tornado开发,但我觉得作为一个go的web框架,还需要提供一些额外的扩展支持. polaris现在已经支持session以及middleware,主要参加djang ...
- Linux0.11 创建进程的过程分析--fork函数的使用
/* * linux/kernel/fork.c * * (C) 1991 Linus Torvalds */ /* 注意:signal.c和fork.c文件的编译选项内不能有vc变量优化选项/Og, ...
- JAVA应用程序转换为Applet
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41673295 将一个图形的JAVA应用程序转换为能够嵌入在 ...
- MySQL学习笔记_8_SQL语言基础复习
SQL语言基础复习 一.概述 SQL语句注释方式 1)以"#"开头直到行尾的所有内容都是注释 2)以"--"(--后还有一个空格)开头直到行尾的所有内容都是注释 ...
- 集群通信组件tribes之集群的平行通信
前面的集群成员维护服务为我们提供了集群内所有成员的地址端口等信息,可以通过MembershipService可以轻易从节点本地的成员列表获取集群所有的成员信息,有了这些成员信息后就可以使用可靠的TCP ...
- GDB 资料汇总
很全的关于 GDB 调试的指导: GDB中应该知道的几个调试方法 用 GDB 调试程序 100个gdb调试小技巧 CGDB中文手册 Beej's Quick Guide to GDB
- Cocos2D v2.0至v3.x简洁转换指南(四)
实现通用的update方法 在Cocos2d 2.x你需要2个步骤去实现在每帧调用update方法: // 1) schedule update [self scheduleUpdate]; ... ...
- 谈谈javascript 中的函数问题
聊聊javascript中的函数 本文可作为李刚<疯狂htmlcssjavas讲义>的学习笔记 先说一个题外话 前几天在知乎上流传着一个对联 上联是雷锋推到雷峰塔 nnd 这是什么对联? ...
- mysql进阶(五)数据表中带OR的多条件查询
MySQL数据表中带OR的多条件查询 OR关键字可以联合多个条件进行查询.使用OR关键字时: 条件 1) 只要符合这几个查询条件的其中一个条件,这样的记录就会被查询出来. 2) 如果不符合这些查询条件 ...