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. gcov辅助脚本

    gcov辅助脚本(金庆的专栏)代码覆盖测试查看结果时,需要进入代码所在目录,调用gcov,然后vi查看.因为代码目录结构复杂,进出子目录太麻烦,所以用以下脚本直接生成与查看.一般是用TSVN列出有更改 ...

  2. UNIX环境高级编程——计算机体系结构基础知识

    无论是在CPU外部接总线的设备还是在CPU内部接总线的设备都有各自的地址范围,都可以像访问内存一样访问,很多体系结构(比如ARM)采用这种方式操作设备,称为等都会产生异常. 通常操作系统把虚拟地址空间 ...

  3. Android studio中的一次编译报错’Error:Execution failed for task ':app:transformClassesWithDexForDebug‘,困扰了两天

    先说下背景:随着各种第三方框架的使用,studio在编译打包成apk时,在dex如果发现有相同的jar包,不能创建dalvik虚拟机.一个apk,就是一个运行在linux上的一个虚拟机. 上图就是一直 ...

  4. webview与js交互

     对于android初学者应该都了解webView这个组件.之前我也是对其进行了一些简单的了解,但是在一个项目中不得不用webview的时候,发现了webview的强大之处,今天就分享一下使用we ...

  5. RecyclerView 实现横向滚动效果

    我相信很久以前,大家在谈横向图片轮播是时候,优先会选择具有HorizontalScrollView效果和ViewPager来做,不过自从Google大会之后,系统为我们提供了另一个控件Recycler ...

  6. MinerUrl.java 解析页面后存储URL类

    MinerUrl.java 解析页面后存储URL类 package com.iteye.injavawetrust.miner; /** * 解析页面后存储URL类 * @author InJavaW ...

  7. HashMap与HashTable面试宝典

    u012233832的专栏 初生牛犊 目录视图 摘要视图 订阅 写博客,送money.送书.送C币啦   7-8月博乐推荐文章    砸BUG 得大奖 100%中奖率   微信开发学习路线高级篇上线  ...

  8. Android学习之旅-android系统服务的启动过程以及分类(90)

    读了android开发精要这本书,所以我把书中的比较精彩的地方截图了,一块分享一下

  9. saiku查询结果返回地址(saiku交互过程)

    提交mdx语句,执行后, 查询结果的获得,访问这个地址: http://99.999.99.99:8080/saiku/rest/saiku/anonymousUser/query/4FF7D01E- ...

  10. Cocos2D的随机数生成函数

    有很多种方法生成随机数.但是只有arc4random函数生成的最接近于"真随机(truly random)"数.(而且不需要种子) 其变体函数arc4random_uniform生 ...