一、静态代理实现

  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. 史上最全的MySQL高性能优化实战总结!

    1.1 前言 MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多 ...

  2. Spring 的 Bean 管理(注解方式)

    Spring 的 Bean 管理(注解方式) 1. 导入必要的 jar 包和 xml 文件 使用注解需要导入 spring-aop 的 jar 包. applicationContext.xml 文件 ...

  3. 25-Perl CGI编程

    1.Perl CGI编程什么是CGICGI 目前由NCSA维护,NCSA定义CGI如下:CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如:HTT ...

  4. Java Web ActiveMQ与WebService的异同

    Webservice 和MQ(MessageQueue)都是解决跨平台通信的常用手段 一.WebService:用来远程调用服务,达到打通系统.服务复用的目的.是SOA系统架构——面向服务架构的体现. ...

  5. python 的面试题总汇

    函数作用域; LEGB : L>E>G>B L : local函数内部作用域 E : enclosing函数内部与内嵌函数之间 G : global全局作用域 B : build-i ...

  6. jvm之java类加载机制和类加载器(ClassLoader),方法区结构,堆中实例对象结构的详解

    一.类加载或类初始化:当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤. 二.类加载时机:  1 ...

  7. React中使用遍历

    1.使用for(let item of items){} render(){ var itemList = [] for(let item of items){ itemList.push(<I ...

  8. Linux--目录属性

    目录的读属性:表示具有读取目录结构清单的权限.使用ls命令可以将该目录中的文件和子目录的内容列出来. 目录的写属性:表示具有更改目录结构清单的权限.包括以下操作: 建立新的文件与目录 删除已经存在的文 ...

  9. Apache Shiro漏洞复现

    利用burp dns进行检测,脚本如下: import sys import uuid import base64 import subprocess from Crypto.Cipher impor ...

  10. JavaWeb【五、内置对象】

    简介 Web容器创建的一组对象,不用new即可使用. 共有9种,out.request.response.session.application,五种比较常用,page.pageContent.exc ...