动态代理,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 ...
随机推荐
- PS进程及杀掉进程!
1.程序和进程的关系(1)程序 保存在硬盘.光盘等介质中的可执行代码和数据 静态保存的代码 (2)进程 在 CPU 及内存中运行的程序代码 动态执行的代码 父.子进程:每一个进程可以创建一个或多个进程 ...
- 【网摘】模仿 placeholder 属性
/*为空时显示 element attribute content*/ .project-task-edit .subtask-body-txt:empty:before { content: att ...
- 第七届蓝桥杯javaB组真题解析-抽签(第五题)
题目 /* 抽签 X星球要派出一个5人组成的观察团前往W星. 其中: A国最多可以派出4人. B国最多可以派出2人. C国最多可以派出2人. .... 那么最终派往W星的观察团会有多少种国别的不同组合 ...
- Ubuntu将Python3软连接到Python
sudo ln -s /usr/bin/python3 /usr/bin/python
- Unknown column '××' in 'where clause',出现这个问题,如何处理?
stmt.executeQuery("select * from user where username = " + name); 执行上述代码就会引发该错误. 原因是:拼凑sql ...
- PTA的Python练习题(三)
继续在PTA上编写Python的编程题. 从 第2章-11 求平方与倒数序列的部分和 开始 1. a,b=map(int,input().split()) s=0 while(a<=b): s= ...
- C 语言入门第八章--C语言预处理命令
例如:#include ,这种以#号开头的命令称为预处理命令. ===C语言宏定义(#define的用法)==== #define 叫做宏定义命令,它也是C语言预处理命令的一种.所谓宏定义,就是用一个 ...
- iis下发布MVC网站
1.首先检查有没有安装iis,没有的话先安装iis 2. 3.选择应用程序池的时候看有没有asp.net 4.0 如果没有先安装. 首先以管理员身份打开“运行”输入cd C:\Windows\Micr ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 安装
所有平台的 MySQL 下载地址为: MySQL 下载:https://dev.mysql.com/downloads/mysql/ 注意:安装过程我们需要通过开启管理员权限来安装,否则会由于权限不足 ...
- Mp3下载