Spring——代理实现AOP
一、静态代理实现
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的更多相关文章
- spring 代理注解 <aop:aspectj-autoproxy />
spring默认使用jdk的代理方式,使用jdk的代理方式我们知道,代理的类需要实现一个接口,若果没有就会报,java.lang.NoSuchMethodException: com.sun.prox ...
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
一.为什么需要代理模式 假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: package com.zhangguo.Spring041.aop01; public class Mat ...
- Spring 代理对象,cglib,jdk的问题思考,AOP 配置注解拦截 的一些问题.为什么不要注解在接口,以及抽象方法.
可以被继承 首先注解在类上是可以被继承的 在注解上用@Inherited /** * Created by laizhenwei on 17:49 2017-10-14 */ @Target({Ele ...
- 8 -- 深入使用Spring -- 4...6 AOP代理:基于注解的XML配置文件的管理方式
8.4.6 基于XML配置文件的管理方式 Spring 2.x 提供一个新的aop:命名空间来定义切面.切入点和增强处理. XML配置方式优点: ⊙ 如果应用没有使用JDK 1.5 以上版本,那么应用 ...
- 2018.12.24 Spring中的aop演示(也就是运用aop技术实现代理模式)
Aop的最大意义是:在不改变原来代码的前提下,也不对源代码做任何协议接口要求.而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码. 1.spring中的aop演示 aop:面向方面编程.不 ...
- spring (反射+代理+DI+AOP)
spring https://baijiahao.baidu.com/s?id=1620606848227713760&wfr=spider&for=pc 反射 https://bl ...
- 这一次搞懂Spring代理创建及AOP链式调用过程
文章目录 前言 正文 基本概念 代理对象的创建 小结 AOP链式调用 AOP扩展知识 一.自定义全局拦截器Interceptor 二.循环依赖三级缓存存在的必要性 三.如何在Bean创建之前提前创建代 ...
- 使用Java原生代理实现AOP
### 本文由博主柒.原创,转载请注明出处 ### 完整源码下载地址 [https://github.com/MatrixSeven/JavaAOP](https://github.com/Matri ...
- Spring 3.0 AOP (一)AOP 术语
关于AOP.之前我已写过一个系列的随笔: <自己实现简单的AOP>,它的关注点在于实现.实现语言是C#,实现方式为 自定义实现 RealProxy 抽象类.重写Invoke方法,以便进行方 ...
随机推荐
- 交替方向乘子法(ADMM)的原理和流程的白话总结
交替方向乘子法(ADMM)的原理和流程的白话总结 2018年08月27日 14:26:42 qauchangqingwei 阅读数 19925更多 分类专栏: 图像处理 作者:大大大的v链接:ht ...
- Windows authentication for WCF web services error
WCF Web服务的Windows身份验证在部署到IIS时,默认网站添加应用程序的方式.浏览运行.svc文件报错. 错误代码: The authentication schemes configure ...
- 11-Perl 运算符
1.Perl 运算符运算符是一种告诉编译器执行特定的数学或逻辑操作的符号,如: 3+2=5.Perl 语言内置了丰富的运算符,我们来看下常用的几种: 算术运算符,比较运算符,逻辑运算符,赋值运算符,位 ...
- c# winform 窗体间的传值
1.父窗体传值给子窗体: 1) 父窗体: FrmXX frm = ,); frm.Owner = this; frm.ShowDialog(); 子窗体: ; public FrmXX(int ty, ...
- mvc布局(一)
negut添加Optimization @System.Web.Optimization.Styles.Render( "~/Content/styles/css/font-awesome. ...
- 你不知道的css各类布局(二)之流体布局、液体布局、栅格布局
流体布局 什么是流 在谈论流体布局之前我们需要知道一件事情就是何为“流”,所谓“流”就是“文档流”,是css中的一种基本定位和布局 概念 流体布局(Liquid/Fluid Layout)指的是利用元 ...
- JS基础_代码块
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- H.264 详解
一.MPEG-4说明 1.VOP视频编码技术 VO(Video Object):视频对象,它是场景中的某个物体,最简单的情况下就是矩形框,它是有生命期的,由时间上连续的许多帧构成. VOP(Video ...
- vue开发后台管理系统有感
使用vue开发后台近一个月,今天终于完成得差不多了,期间也遇到很多的问题,所以利用现在的闲暇时间做个总结 使用element-ui基础,这次使用了vue-element-admin(github地址) ...
- Swift调用微信支付宝SDK(Swift4.0)
1.第一步在程序入口注册微信 (支付宝不需要) func application(_ application: UIApplication, didFinishLaunchingWithOption ...