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实现原理详解 ...
随机推荐
- iOS中大流中的自定义cell 技术分享
AppDelegate.m指定根视图 self.window.rootViewController = [[UINavigationController alloc] initWithRootView ...
- 【翻译】Ext JS最新技巧——2015-8-11
原文:Top Support Tips Seth Lemmons:使用棒极了的Awesome Font Ext JS 6附带了一个新的海卫一主题,可以使用Font Awesome字体作为背景图像的图标 ...
- casio计算器计算统计数据
http://blog.csdn.net/pipisorry/article/details/50257319 使用casio计算器计算输入数据均值.标准差和相关系数的方法,lz使用casio fx8 ...
- leetcode 生成杨辉三角形, 118 119 Pascal's Triangle 1,2
Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Retu ...
- javascript之自定义数组工具对象
<pre name="code" class="html">/* 需求:编写一个js文件,在js文件中自定义一个数组工具对象, 该工具对象要有一个找 ...
- FFmpeg深入分析(一)
最近在做一个关于监控的项目,要在iphone 客户端实现播放监控的实时视频以及录像视频.使用到了FFmpeg,看到这篇文章,写的非常不错.转自:http://blog.chinaunix.net/ui ...
- spring2.5与hibernate3升级后的bug
手头有一个项目,使用的是struts2 hibernate3 spring2.5 是之前的老项目了,spring与hibernate的版本都比较低 自己看了最新的spring4与hibernate4, ...
- Android进阶(十六)子线程调用Toast报Can't create handler inside thread that has not called Looper.prepare() 错误
原子线程调用Toast报Can't create handler inside thread that has not called Looper.prepare() 错误 今天用子线程调Toast报 ...
- Pixelmetrix :OTT Media Grinder (OTT TV 质量评价设备)
有关OTT TV 质量评价方法方面的研究少之又少.国内貌似还几乎没有相关的研究.不过在国外已经找到相关的产品了,翻译了一下产品手册的部分内容,很有参考价值,尤其是其提出的8个指标. 概述 OTT Me ...
- [Ext.Net]客户关系管理系统
本人在企业中非专业人士,交流学习. 1.登录 2.系统主界面 3.用户与角色 3.菜单管理 4.角色与授权 5.登陆日志 6.简易工作流 7.客户分类 8.客户管理 9.报价管理 业务员反馈 报价明细 ...