一、静态代理实现

  1.接口(抽象主题)

  

  2.接口的实现类(真实主题)

  

  3.代理类(代理主题)

  

  4.测试类:

     ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        ProxySubject proxySubject =(ProxySubject) context.getBean("proxySubject");
        proxySubject.doSome();

二、JDK动态代理

  JDK动态代理所用到的代理类在程序调用到代理类对象时才由JVM真正创建,JVM根据传进来的 业务实现类对象 以及 方法名 ,动态地创建了一个代理类的class文件并被字节码引擎执行,然后通过该代理类对象进行方法调用。

  1.抽象主题,真实主题与上面一致

  2.动态代理类

package com.cmy.handler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DoSomeBeanFactory implements InvocationHandler {
    private Object target;//这其实业务实现类对象,用来调用具体的业务方法

    public Object bind(Object target) {
        this.target = target;  //接收业务实现类对象参数

        //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
        //创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据,在包装方法是调用真正的业务方法)、接口、handler实现类
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置=====");
        //调用真正的业务方法
        Object result = method.invoke(target, args);
        System.out.println("后置=====");
        return result;
    }
}

  3.测试类

public class ProxyDemo {
    public static void main(String[] args) {
         //创建业务类对象
         Subject subject=new ReallySubject();
         //创建代理对象
         DoSomeBeanFactory factory=new DoSomeBeanFactory();
         //调用bind方法获取代理对象
         Subject proxy = (Subject)factory.bind(subject);
         //调用目标函数
         proxy.say();
    }
}

三、Cglib动态代理

   cglib是针对类来实现代理的,原理是对指定的业务类生成一个子类,并覆盖其中业务方法实现代理。因为采用的是继承,所以不能对final修饰的类进行代理。

  新建代理类

package com.cmy.handler;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

public class DoSomeBeanCGlib implements MethodInterceptor{
    private Object target;//业务类对象,供代理方法中进行真正的业务方法调用

    //相当于JDK动态代理中的绑定
    public Object getInstance(Object target) {
        this.target = target;  //给业务对象赋值
        Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
        enhancer.setSuperclass(this.target.getClass());  //为加强器指

    //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实    现intercept()方法进行拦
        enhancer.setCallback(this);
        // 创建动态代理类对象并返回
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("预处理——————");
        methodProxy.invokeSuper(o, objects); //调用业务类(父类中)的方法
        System.out.println("调用后操作——————");
        return null;
    }
}

  总结:

  • JDK动态代理是通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法;
  • CGlib动态代理是通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理;
  • 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
  • 如果目标对象实现了接口,可以强制使用CGLIB实现AOP
  • [aop:config proxy-target-class="true"] 强制切换成CGLIB动态代理
  • 如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

Spring——代理实现AOP的更多相关文章

  1. spring 代理注解 <aop:aspectj-autoproxy />

    spring默认使用jdk的代理方式,使用jdk的代理方式我们知道,代理的类需要实现一个接口,若果没有就会报,java.lang.NoSuchMethodException: com.sun.prox ...

  2. Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC

    一.为什么需要代理模式 假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: package com.zhangguo.Spring041.aop01; public class Mat ...

  3. Spring 代理对象,cglib,jdk的问题思考,AOP 配置注解拦截 的一些问题.为什么不要注解在接口,以及抽象方法.

    可以被继承 首先注解在类上是可以被继承的 在注解上用@Inherited /** * Created by laizhenwei on 17:49 2017-10-14 */ @Target({Ele ...

  4. 8 -- 深入使用Spring -- 4...6 AOP代理:基于注解的XML配置文件的管理方式

    8.4.6 基于XML配置文件的管理方式 Spring 2.x 提供一个新的aop:命名空间来定义切面.切入点和增强处理. XML配置方式优点: ⊙ 如果应用没有使用JDK 1.5 以上版本,那么应用 ...

  5. 2018.12.24 Spring中的aop演示(也就是运用aop技术实现代理模式)

    Aop的最大意义是:在不改变原来代码的前提下,也不对源代码做任何协议接口要求.而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码. 1.spring中的aop演示 aop:面向方面编程.不 ...

  6. spring (反射+代理+DI+AOP)

    spring  https://baijiahao.baidu.com/s?id=1620606848227713760&wfr=spider&for=pc 反射 https://bl ...

  7. 这一次搞懂Spring代理创建及AOP链式调用过程

    文章目录 前言 正文 基本概念 代理对象的创建 小结 AOP链式调用 AOP扩展知识 一.自定义全局拦截器Interceptor 二.循环依赖三级缓存存在的必要性 三.如何在Bean创建之前提前创建代 ...

  8. 使用Java原生代理实现AOP

    ### 本文由博主柒.原创,转载请注明出处 ### 完整源码下载地址 [https://github.com/MatrixSeven/JavaAOP](https://github.com/Matri ...

  9. Spring 3.0 AOP (一)AOP 术语

    关于AOP.之前我已写过一个系列的随笔: <自己实现简单的AOP>,它的关注点在于实现.实现语言是C#,实现方式为 自定义实现 RealProxy 抽象类.重写Invoke方法,以便进行方 ...

随机推荐

  1. 简单的pycharm使用秘籍视频

    ttp://edu.51cto.com/center/course/lesson/index?id=163794 这个免费视频是我自己找的别人的,一些常用的基本上都还有,所以说善用百度之类的搜索引擎很 ...

  2. java 异常捕捉 ( try catch finally ) 你真的掌握了吗?

    掌握下面几条原则就可以完全解决“当try.catch.finally遭遇return”的问题. 原则:1.finally语句块中的代码是一定会执行的,而catch块中的代码只有发生异常时才会执行. 2 ...

  3. qt tableview使用

    Qt::CheckState checkSibling(QStandardItem * item); void treeItem_checkAllChild(QStandardItem * item, ...

  4. SQL基础:语句执行顺序

    SQL入门 select * from table; SQL实战题目 有下面一个表 t ,存储了每个商品类别的成交明细,我们需要通过下面这张表获取订单量大于10对应的类别,并从中取出订单量前3的商品类 ...

  5. 5 java 笔记

    1  建议不要在循环体内修改循环变量的值 2 java语言没有提供goto语句来控制程序的跳转 2 java语言同样也提供了continue和break关键字来控制程序的循环结构 3 java中的标签 ...

  6. tomcat启动程序乱码和tomcat启动程序的标题乱码处理

    启动程序运行中的文字乱码: 解决方案: 找到Tomcat目录下conf文件夹中的logging.properties文件, 打开logging.properties文件,找到文件中的java.util ...

  7. 论文笔记:Unsupervised Domain Adaptation by Backpropagation

    14年9月份挂出来的文章,基本思想就是用对抗训练的方法来学习domain invariant的特征表示.方法也很只管,在网络的某一层特征之后接一个判别网络,负责预测特征所属的domain,而后特征提取 ...

  8. python常用模块:项目目录规范、定制程序入口、自定义模块、引用变量、time和datetime模块

    今天讲课内容有两大部分: 一.文件目录规范二.定制程序入口三.使用标准目录后四.常规函数time.datetime 一.标准目录规范 之前用过的案例atm机+购物商城代码过长,在学习了模块和包以后,我 ...

  9. 8.2.ZooKeeper应用场景

    7.ZooKeeper应用举例 为了方便大家理解ZooKeeper,在此就给大家举个例子,看看ZooKeeper是如何实现的他的服务的,我以ZooKeeper提供的基本服务分布式锁为例. 7.1 分布 ...

  10. codeforces Educational Codeforces Round 65 (补完)

    C News Distribution 并查集水题 D Bicolored RBS 括号匹配问题,如果给出的括号序列nesting depth为n,那么最终可以分成两个nesting depth为n ...