SpringAOP
Aspect Orient Programming,面向切面编程
使用步骤
- 定义业务组件
- 定义切点
- 定义增强通知
使用方式
实现原理
采用JDK动态代理和CGLib动态代理实现
- 如果目标对象有实现接口,则使用JDK动态代理
- 如果没有实现接口,则使用CGLib动态代理
JDK动态代理
通过反射实现代理
步骤:
- 定义实现InvocationHandler接口的处理器
- 通过**Proxy.newInstance(类加载器,所有代理目标实现的接口,处理器)**来获取代理对象
- 使用代理对象的方法
优点:
- 原生,不需要其他依赖
- 生成代理类的速度快
缺点:
- 通过接口的方法来织入增强方法,因此目标必须需要实现接口
- 执行方法的速度相对较慢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class JdkProxySubject implements InvocationHandler { private Subject subject; public JdkProxySubject(Subject subject) { this.subject = subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before 前置通知"); Object result = null; try { result = method.invoke(subject, args); }catch (Exception ex) { System.out.println("ex: " + ex.getMessage()); throw ex; }finally { System.out.println("after 后置通知"); } return result; } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class Main { public static void main(String[] args) { InvocationHandler handler = new JdkProxySubject(new RealSubject());
Subject proxySubject = (Subject)Proxy.newProxyInstance(Main.class.getClassLoader(), new Class[]{Subject.class}, handler);
proxySubject.request(); }
|
CGLib动态代理
通过操作字节码实现代理
Cglib的实现是在字节码的基础上的,并且使用了开源的ASM读取字节码,对类实现增强功能的。