一、静态代理实现

  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. 怎样理解 Vue 中的 v-if 和 v-show ?

    1. v-if 实现了真正的 条件渲染, 条件为真时, 节点被创建, 相应的监听函数也会生效, 条件为假时, 节点被销毁, 触发事件监听函数不会生效. 而 v-show 只是使用了 display:n ...

  2. 【原创】大叔问题定位分享(33)oozie提交任务报错ArithmeticException: / by zero

    oozie提交workflow后执行task报错: 2019-07-04 17:19:00,559 ERROR [RMCommunicator Allocator] org.apache.hadoop ...

  3. ns nat rule

    ns nat rule NAT实现方式: NAT的实现方式有三种,即静态转换(Static Nat).动态转换(Dynamic Nat) 和 端口多路复用(OverLoad). 静态转换是指将内部网络 ...

  4. 1 asp.net 中如何把用户控件应用于母版页

    1 创建用户控件 2 在母版页中注册用户控件 3 使用 <%@ Master Language="C#" AutoEventWireup="true" C ...

  5. 第十三章、元类(metaclass)

    目录 第十三章.元类(metaclass) 一.什么是元类 二.为什么用元类 第十三章.元类(metaclass) 一.什么是元类 在python中一切皆对象,那么我们用class关键字定义的类本身也 ...

  6. 【转】tar命令详解

    原文:http://www.cnblogs.com/qq78292959/archive/2011/07/06/2099427.html tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压 ...

  7. ubuntu系统搭建samba服务

    安装samba服务 # apt-get install samba 创建一个samba服务的分享目录 # mkdir /share 创建一个samba服务限制的用户及组 #useradd public ...

  8. C++ 批量打开写入文件

    用到了C++17的filesystem 库 说明:这个函数主要是用来处理日志中不同Thread的日志,主要目的是将不同Thread的日志写到不同的文件中 int GetThreadTime(const ...

  9. mysql服务脚本

    #!/bin/bash #*************************** #* copyleft huihui 2015-08-11 #**************************** ...

  10. java8学习之Lambda表达式继续探讨&Function接口详解

    对于上次[http://www.cnblogs.com/webor2006/p/8186039.html]已经初步引入的Java8中Stream流的概念,其中使用了map的操作,它需要接受一个Func ...