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. Android官方命令深入分析之dmtracedump

    dmtracedump是一个根据log文件生成图形化调用堆栈的工具(除了Traceview之外). dmtracedump的用法: dmtracedump [-ho] [-s sortable] [- ...

  2. RabbitMQ消息队列(五):Routing 消息路由

        上篇文章中,我们构建了一个简单的日志系统.接下来,我们将丰富它:能够使用不同的severity来监听不同等级的log.比如我们希望只有error的log才保存到磁盘上. 1. Bindings ...

  3. moonmq: 用go实现的高性能message queue

    介绍 moonmq是一个用go实现的高性能消息队列系统,后续准备用于我们消息推送服务以及各个后台的异步任务. 在设计上面,moonmq主要借鉴了rabbitmq以及rocketmq相关的思想,但是做了 ...

  4. Android开机键失灵启动手机的解决办法

    问题描述 Android手机的关机键损坏,无法开机. 解决方法 将手机通过USB线链接电脑,进入命令行,找到adb命令所在目录,运行如下命令: adb reboot 注意:用这种方法的前提是,如果你当 ...

  5. Miscellaneous Articles

    标记一下,慢慢看  http://www.oracle-base.com/articles/misc/articles-misc.php Miscellaneous Articles DBA Deve ...

  6. 【一天一道LeetCode】#69. Sqrt(x)

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Impleme ...

  7. OC内存管理-OC笔记

    内存管理细节:http://blog.sina.com.cn/s/blog_814ecfa90102vus2.html 学习目标 1.[理解]内存管理 2.[掌握]第一个MRC程序 3.[掌握]内存管 ...

  8. 【翻译】使用Ext JS设计响应式应用程序

    原文:Designing Responsive Applications with Ext JS 在当今这个时代,用户都希望Web应用程序无论在形状还是大小上,既能在桌面电脑,也能在移动设备上使用.使 ...

  9. Cocos2D v2.0至v3.x简洁转换指南(五)

    资源管理 如果你没有计划用SpriteBuilder,你可以继续使用后缀去管理各种不同解决方案中的图像. 首先,你需要在AppDelegate.m中将[CCBReader configrueCCFil ...

  10. mysql进阶(七)limit的用法

    limit是mysql的语法 select * from table limit m,n 其中m是指记录开始的index,从0开始,表示第一条记录 n是指从第m+1条开始,取n条. select *  ...