AOP的底层原理

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

什么是AOP?

全称为Aspect Oriented Programming: 面向切面编程. 通过预编译方式和运行期动态代理的方式实现功能的一种技术.

利用AOP可以对业务逻辑的各个部分进行隔离, 从而使得业务逻辑各部分之间的耦合度降低, 提高程序的可重用性, 并且提高开发效率.

AOP作用

AOP可以做到在程序的运行期间, 不修改业务代码的情况下对方法进行功能的增强.

AOP优势

  1. AOP可以减少重复的代码
  2. AOP可以在很大程度上提高开发效率
  3. AOP编写出来的代码, 可以很方便的进行维护

AOP的实现原理

AOP的底层是通过spring提供的动态代理技术实现的. 在程序的运行期间, spring动态生成代理对象, 代理对象的方法在执行时就可以进行增强功能的介入, 从而完成目标对象方法的功能增强.

基于JDK的动态代理

目标接口

1
2
3
csharp复制代码 public interface TargetInterface {
     public void save();
 }

目标类

1
2
3
4
5
csharp复制代码 public class Target implements TargetInterface {
     public void save() {
         System.out.println("do...");
    }
 }

功能增强类

1
2
3
4
5
6
7
8
9
csharp复制代码 public class Advice {
     public void before() {
         System.out.println("前置增强");
    }
 ​
     public void after() {
         System.out.println("后置增强");
    }
 }

基于jdk的功能增强

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
scss复制代码 // 获取目标对象
 final Target target = new Target();
 ​
 // 获取增加对象
 final Advice advice = new Advice();
 ​
 TargetInterface ti = (TargetInterface) Proxy.newProxyInstance(
         target.getClass().getClassLoader(),
         target.getClass().getInterfaces(),
         new InvocationHandler() {
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 // 前置增强
                 advice.before();
                 Object invoke = method.invoke(target, args);
 ​
                 // 后置增强
                 advice.after();
                 return invoke;
            }
        }
 );
 ​
 // 调用方法
 ti.save();

基于cglib的动态代理

目标类

1
2
3
4
5
csharp复制代码 public class Target {
     public void save() {
         System.out.println("do...");
    }
 }

功能增强类

1
2
3
4
5
6
7
8
9
csharp复制代码 public class Advice {
     public void before() {
         System.out.println("前置增强");
    }
 ​
     public void after() {
         System.out.println("后置增强");
    }
 }

基于cglib的功能增强

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
26
27
28
29
30
31
32
33
34
scss复制代码 // 获取目标对象
 final Target target = new Target();
 ​
 // 获取增强对象
 final Advice advice = new Advice();
 ​
 // 创建增强器
 Enhancer enhancer = new Enhancer();
 ​
 // 设置目标对象
 enhancer.setSuperclass(Target.class);
 ​
 // 设置回调
 enhancer.setCallback(
         new MethodInterceptor() {
             public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
 ​
                 // 前置增强
                 advice.before();
 ​
                 Object invoke = method.invoke(target, objects);
 ​
                 // 后置增强
                 advice.after();
                 return invoke;
            }
        }
 );
 ​
 // 创建代理对象
 Target proxy = (Target) enhancer.create();
 ​
 // 执行目标对象的方法
 proxy.save();

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%