动态代理,AOP和Spring
笔记
1. 什么是AOP?
Aspect-Oriented Programming 面向切面编程,关注一个统一的切面,相对于OOP(面向对象编程)。
适合的场景:
- 日志
- 缓存
- 鉴权
如果用OOP来做怎么办?
- 装饰器模式
2. 装饰器模式 (OOP, 静态代理)
Decorator pattern:
动态地为一个对象增加功能,但是不改其结构。
public interface DataService {
String a(int i);
String b(int i);
}
public class DataServiceImpl implements DataService {
@Override
public String a(int i) {
return UUID.randomUUID().toString();
}
@Override
public String b(int i) {
return UUID.randomUUID().toString();
}
}
public class Main {
static DataService service = new CacheDecorator(new LogDecorator(new DataServiceImpl()));
public static void main(String[] args) {
System.out.println(service.a(1));
System.out.println(service.b(1));
}
}
假如是class,就会有浪费。
3. AOP动态代理
public class LogProxy implements InvocationHandler {
private DataService delegate;
public LogProxy(DataService delegate) {
this.delegate = delegate;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName() + " is invoker " + Arrays.toString(args));
Object result = method.invoke(delegate, args);
System.out.println(method.getName() + " is finished: " + result);
return result;
}
}
public class Main {
static DataService service = new DataServiceImpl();
public static void main(String[] args) {
DataService dataService = (DataService) Proxy.newProxyInstance(
service.getClass().getClassLoader(),
new Class[]{DataService.class},
new LogProxy(service));
dataService.a(1);
dataService.b(3);
}
}
优点:方便,不需要依赖任何第三方库
缺点:功能受限,只能用于接口 (源代码中接收参数为interface,如果是class会报异常)
4. 如果是class怎么办?
CGLIB/ByteBuddy字节码生成
public class Main {
static DataServiceImpl service = new DataServiceImpl();
public static class LogInterceptor implements MethodInterceptor {
private DataServiceImpl delegate;
public LogInterceptor(DataServiceImpl delegate) {
this.delegate = delegate;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println(method.getName() + " is invoker " + Arrays.toString(objects));
Object result = method.invoke(delegate, objects);
System.out.println(method.getName() + " is finished: " + result);
return result;
}
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(DataServiceImpl.class);
enhancer.setCallback(new LogInterceptor(service));
DataServiceImpl enhancedService = (DataServiceImpl) enhancer.create();
enhancedService.a(1);
enhancedService.b(2);
}
// 这里会动态生成一个叫做DataServiceImpl$$EnhancerByCGLIB$$9bce1175@651的类,它是动态生成出来,并且是继承我们的DataServiceImpl的。
优点:强大,不受接口的限制
缺点:需要额外引用第三方库,不能增强final类/final/private方法(因为原理是继承)。
动态代理,AOP和Spring的更多相关文章
- CgLib动态代理学习【Spring AOP基础之一】
如果不了解JDK中proxy动态代理机制的可以先查看上篇文章的内容:Java动态代理学习[Spring AOP基础之一] 由于Java动态代理Proxy.newProxyInstance()的时候会发 ...
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...
- Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。
借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...
- Spring-Boot的动态代理AOP原理
前言 Spring AOP使用了动态代理技术,动态代理在业界比较流行的实现方式有,CGLIB,Javassist,ASM等等. Spring动态代理实现方式 Spring采用了JDK和CGLIB两种方 ...
- 浅析DispatchProxy动态代理AOP
浅析DispatchProxy动态代理AOP(代码源码) 最近学习了一段时间Java,了解到Java实现动态代理AOP主要分为两种方式JDK.CGLIB,我之前使用NET实现AOP切面编程,会用Fil ...
- Java动态代理学习【Spring AOP基础之一】
Spring AOP使用的其中一个底层技术就是Java的动态代理技术.Java的动态代理技术主要围绕两个类进行的 java.lang.reflect.InvocationHandler java.la ...
- 动态代理以及对应Spring中AOP源码分析
AOP(面向切面编程)在Spring中是被广泛应用的(例如日志,事务,权限等),而它的基本原理便是动态代理. 我们知道动态代理有两种:基于JDK的动态代理以及基于CGlib动态代理.以下是两种动态代理 ...
- spring中使用动态代理(AOP)
spring是整合了BGLIB和JDK两种动态代理 示例:使用CGLIB代理 public class MyCar { private String color = "blue"; ...
- [转]JAVA的动态代理机制及Spring的实现方式
JAVA 代理实现 代理的实现分动态代理和静态代理,静态代理的实现是对已经生成了的JAVA类进行封装. 动态代理则是在运行时生成了相关代理累,在JAVA中生成动态代理一般有两种方式. JDK自带实现方 ...
- 动态代理 aop切面实现事务管理
1.定义接口和实现 public interface UserService { public String getName(int id); public Integer getAge(int id ...
随机推荐
- [运维] 如何解决 nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
环境: 虚拟机 linux centos 7 64 当时正在配置 nginx , 由于解压后的 nginx 默认安装位置是在 /usr/local/ 目录下, 而这个目录是 root 用户才有权限操作 ...
- HDFS核心类FileSystem的使用
一.导入jar包 本次使用的是eclipse操作的,所以需要手动导入jar包 在Hadoop.7.7/share/hadoop里有几个文件夹 common为核心类,此次需要引入common和hdfs两 ...
- redhat7.6 crontab 服务,周期性任务
系统默认安装开启 systemctl status crond.service 查看周期性任务(最多每隔1分钟做周期性任务) crontab -l 系统自身的周期性任务 配置周期性任务 cront ...
- redhat7.6 httpd配置php模块
1.安装php yum install "*php*" -y 2.编辑httpd.conf配置文件 找到LoadModule foo_module modules/mod_fo ...
- 8.1.2hadoop Streaming 作业原理和参数设置
1.1.1 Stream 作业 (1)hadoop streaming Hadoop streaming是hadoop的一个工具,用于运行费java的maper或reducer作业,例 ...
- Python 基础之文件操作与文件的相关函数
一.文件操作 fp =open("文件名",mode="采用的模式",encoding="使用什么编码集")fp 这个变量接受到open的返 ...
- 【协作式原创】自己动手写docker之run代码解析
linux预备知识 urfave cli预备知识 准备工作 阿里云抢占式实例:centos7.4 每次实例释放后都要重新安装go wget https://dl.google.com/go/go1.1 ...
- Java 中 VO、PO、DTO、BO、POJO、DAO 之间的区别与解释
转载:https://www.cnblogs.com/hunmeng/p/11298680.html VO value object:值对象 通常用于业务层之间的数据传递,由new创建,由GC回收. ...
- JS闭包(1)
1.首先看一段代码: var a = 1; function fn1(){ var b = 2; function fn2(){ console.log(a); console.log(b); } } ...
- Struts2学习(六)
拦截器原理 1.如图所示,Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一 ...