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之代理的更多相关文章

  1. springAOP之代理模式

    springAOP指的是在spring中的AOP,什么是AOP,相对于java中的面向对象(oop),在面向对象中一些公共的行为,像日志记录,权限验证等如果都使用面向对象来做,会在每个业务方法中都写上 ...

  2. 深入理解SpringAOP之代理对象

    本篇文章主要带大家简单分析一下AOP的代理对象,至于AOP是什么,如何配置等基础性知识,不在这里讨论.阅读前请先参考:代理模式,在这之前我们需要了解springframework的三个核心接口与get ...

  3. Spring知识点总结(四)之SpringAOP基础 - 代理设计模式

        1. 分析程序中存在的问题(高内聚,低耦合)        通过springIOC DI) 以及注解的使用,成功解决了在程序中层与层之间出现的耦合的问题,但是在很多地方仍然存在非该层应该实现的 ...

  4. spring-AOP动态代理,以及aspectJ的xml配置或注解配置方法,各个拦截器的使用顺序

    package com.itheima.aspect; public class MyAspect { public void check_Permissions(){ System.out.prin ...

  5. Spring-AOP动态代理技术(底层代码)

    1.JDK代理:基于接口的动态代理技术 目标对象必须有接口,目标对象有什么方法,目标接口就有什么方法, 运行期间基于接口动态生成代理对象,所以代理对象也就有目标对象同样的方法. 注意:以下代码只是底层 ...

  6. SpringAOP和AspectJ

    SpringAOP和AspectJ的关系 问题:之前对 SpringAOP和AspectJ的关系感到疑惑,因为曾经在书上看过SpringAOP集成了AspectJ,那么SpringAOP是直接使用了A ...

  7. 完整剖析SpringAOP的自调用

    摘要 spring全家桶帮助java web开发者节省了很多开发量,提升了效率.但是因为屏蔽了很多细节,导致很多开发者只知其然,不知其所以然,本文就是分析下使用spring的一些注解,不能够自调用的问 ...

  8. Spring源码系列(三)--spring-aop的基础组件、架构和使用

    简介 前面已经讲完 spring-bean( 详见Spring ),这篇博客开始攻克 Spring 的另一个重要模块--spring-aop. spring-aop 可以实现动态代理(底层是使用 JD ...

  9. Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现

    上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...

随机推荐

  1. iOS中大流中的自定义cell 技术分享

    AppDelegate.m指定根视图 self.window.rootViewController = [[UINavigationController alloc] initWithRootView ...

  2. 【翻译】Ext JS最新技巧——2015-8-11

    原文:Top Support Tips Seth Lemmons:使用棒极了的Awesome Font Ext JS 6附带了一个新的海卫一主题,可以使用Font Awesome字体作为背景图像的图标 ...

  3. casio计算器计算统计数据

    http://blog.csdn.net/pipisorry/article/details/50257319 使用casio计算器计算输入数据均值.标准差和相关系数的方法,lz使用casio fx8 ...

  4. leetcode 生成杨辉三角形, 118 119 Pascal's Triangle 1,2

    Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Retu ...

  5. javascript之自定义数组工具对象

    <pre name="code" class="html">/* 需求:编写一个js文件,在js文件中自定义一个数组工具对象, 该工具对象要有一个找 ...

  6. FFmpeg深入分析(一)

    最近在做一个关于监控的项目,要在iphone 客户端实现播放监控的实时视频以及录像视频.使用到了FFmpeg,看到这篇文章,写的非常不错.转自:http://blog.chinaunix.net/ui ...

  7. spring2.5与hibernate3升级后的bug

    手头有一个项目,使用的是struts2 hibernate3 spring2.5 是之前的老项目了,spring与hibernate的版本都比较低 自己看了最新的spring4与hibernate4, ...

  8. 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报 ...

  9. Pixelmetrix :OTT Media Grinder (OTT TV 质量评价设备)

    有关OTT TV 质量评价方法方面的研究少之又少.国内貌似还几乎没有相关的研究.不过在国外已经找到相关的产品了,翻译了一下产品手册的部分内容,很有参考价值,尤其是其提出的8个指标. 概述 OTT Me ...

  10. [Ext.Net]客户关系管理系统

    本人在企业中非专业人士,交流学习. 1.登录 2.系统主界面 3.用户与角色 3.菜单管理 4.角色与授权 5.登陆日志 6.简易工作流 7.客户分类 8.客户管理 9.报价管理 业务员反馈 报价明细 ...