笔记

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的更多相关文章

  1. CgLib动态代理学习【Spring AOP基础之一】

    如果不了解JDK中proxy动态代理机制的可以先查看上篇文章的内容:Java动态代理学习[Spring AOP基础之一] 由于Java动态代理Proxy.newProxyInstance()的时候会发 ...

  2. 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

  3. Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。

    借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...

  4. Spring-Boot的动态代理AOP原理

    前言 Spring AOP使用了动态代理技术,动态代理在业界比较流行的实现方式有,CGLIB,Javassist,ASM等等. Spring动态代理实现方式 Spring采用了JDK和CGLIB两种方 ...

  5. 浅析DispatchProxy动态代理AOP

    浅析DispatchProxy动态代理AOP(代码源码) 最近学习了一段时间Java,了解到Java实现动态代理AOP主要分为两种方式JDK.CGLIB,我之前使用NET实现AOP切面编程,会用Fil ...

  6. Java动态代理学习【Spring AOP基础之一】

    Spring AOP使用的其中一个底层技术就是Java的动态代理技术.Java的动态代理技术主要围绕两个类进行的 java.lang.reflect.InvocationHandler java.la ...

  7. 动态代理以及对应Spring中AOP源码分析

    AOP(面向切面编程)在Spring中是被广泛应用的(例如日志,事务,权限等),而它的基本原理便是动态代理. 我们知道动态代理有两种:基于JDK的动态代理以及基于CGlib动态代理.以下是两种动态代理 ...

  8. spring中使用动态代理(AOP)

    spring是整合了BGLIB和JDK两种动态代理 示例:使用CGLIB代理 public class MyCar { private String color = "blue"; ...

  9. [转]JAVA的动态代理机制及Spring的实现方式

    JAVA 代理实现 代理的实现分动态代理和静态代理,静态代理的实现是对已经生成了的JAVA类进行封装. 动态代理则是在运行时生成了相关代理累,在JAVA中生成动态代理一般有两种方式. JDK自带实现方 ...

  10. 动态代理 aop切面实现事务管理

    1.定义接口和实现 public interface UserService { public String getName(int id); public Integer getAge(int id ...

随机推荐

  1. dubbo的dispatcher设置原理

    在上回<Dubbo源代码实现六>中我们已经了解到,对于Dubbo集群中的Provider角色,有IO线程池(默认无界)和业务处理线程池(默认200)两个线程池,所以当业务的并发比较高,或者 ...

  2. Centos10卸载nginx

    1.停止服务 /usr/local/nginx/sbin/nginx -s stop yum remove nginx 2.查看Nginx相关文件 whereis nginx 删除:rm -rf /u ...

  3. [idea] 解决 idea 复制进项目的文件运行时无法找到的问题

    解决方法一: Rebuild后,重启项目 解决方法二:

  4. Dart语言学习(十一) Dart异常处理

    异常是表示发生了意外的错误,如果没有捕获异常,引发异常的隔离程序将被挂起,并且程序将被终止: Dart代码可以抛出并捕获异常,但与java相反,Dart的所有异常都是未检查的异常,方法不声明它们可能抛 ...

  5. Java 笔试题

    有一些还是存在问题,欢迎大家一起探讨. 在Java类中,使用以下( )声明语句来定义公有的int型常量MAX. A. public int MAX = 100; B. final int MAX = ...

  6. scrapy-redis分布式

    scrapy是python界出名的一个爬虫框架,提取结构性数据而编写的应用框架,可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 虽然scrapy 能做的事情很多,但是要做到大规模的分 ...

  7. IVM sdk command

    1.load sdk shell ./auto_load_user.sh 2.查看all端口状态 IVM:0>ifcs show devport 3.查看个别端口状态 IVM:0>ifcs ...

  8. Linux--info命令 ,help命令,man命令(帮助)

    Info和man命令一样都是帮助类文件 Info文件不仅包含信息,而且还包含连接到其他info文件的链接. 如何使用info显示希望的内容 * 如何操纵Info系统 * 如何显示Info的帮助信息. ...

  9. MNIST手写数字分类simple版(03-2)

    simple版本nn模型 训练手写数字处理 MNIST_data数据   百度网盘链接:https://pan.baidu.com/s/19lhmrts-vz0-w5wv2A97gg 提取码:cgnx ...

  10. 用C/C++创建windows服务程序

    转载:https://blog.csdn.net/chenyujing1234/article/details/8023816 一.演示过程下方代码演示了如何使用vs(C/C++)创建windows服 ...