博客
关于我
Spring 框架之 AOP 原理深度剖析
阅读量:796 次
发布时间:2023-02-26

本文共 3823 字,大约阅读时间需要 12 分钟。

Spring AOP实现原理解析

Spring AOP(Aspect Oriented Programming,面向切面编程)是一种面向切面编程的框架,它能够统一管理多个目标对象,并在不修改原有业务代码的前提下,增加额外功能。其实现过程主要依赖于代理(Proxy)和动态代理(Dynamic Proxy)技术。本文将深入分析Spring AOP的实现原理。

一、AOP的基本概念

AOP通过将应用程序划分为重要部分,并将那些跨越这些部分的关注点分离出来,从而更好地定义业务逻辑。AOP的核心概念包括:

  • 切面(Aspect):是指被织入目标类中的功能代码。对于Java来说,通常是方法、构造器或类的特定点上的代码。切面可以包括前置通知、后置通知、环绕通知、异常通知和最终通知等,具体根据业务需求自定义实现。
  • 连接点(Join Point):是指切面将被织入目标对象的位置。对于Java来说,通常是某个方法的执行点或某个构造器的创建点。
  • 切入点(Pointcut):是连接点的集合,定义了哪些连接点需要被织入目标对象中。
  • 通知(Advice):包括各种类型的切面代码,如前置通知、后置通知、环绕通知、异常通知和最终通知等。
  • 织入(Weaving):是指将切面代码编织到目标对象中的过程,可以在编译时、加载时或运行时进行。Spring AOP以动态代理技术为主要方式进行织入。
  • 引入(Introduction):允许我们向现有的类添加新方法和属性,这些方法和属性并不在原先的类定义中,而是在引入的接口中定义。

二、AOP实现的三种方式

在介绍Spring AOP实现原理之前,我们先了解实现AOP的三种方式:静态代理、JDK动态代理和CGLIB动态代理。

1. 静态代理

静态代理是指在编译时就已经确定需要被代理的类和方法,代理类在编译时就已经存在。其优点是运行效率高,但缺点是灵活性不足,只能代理预先定义好的类和方法。

以一个简单的示例说明静态代理的原理:

public interface Subject {
void request();
}
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject is handling the request.");
}
}
public class ProxySubject implements Subject {
private Subject realSubject;
public ProxySubject(Subject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("ProxySubject is handling the request.");
realSubject.request();
}
}

2. JDK动态代理

JDK动态代理是基于Java反射机制实现的动态代理技术。它通过动态生成代理类的方式实现对目标对象的代理。在这种方式下,目标对象不需要实现特定的接口,动态代理类会根据目标对象的方法进行动态代理。

例如,可以通过JDK动态代理实现对MyService接口的动态代理:

public interface MyService {
void doSomething();
void doSomethingElse();
}
public class MyServiceImpl implements MyService {
@Override
public void doSomething() {
System.out.println("MyServiceImpl doSomething()");
}
@Override
public void doSomethingElse() {
System.out.println("MyServiceImpl doSomethingElse()");
}
}
public class MyDynamicProxy implements InvocationHandler {
private MyService target;
public MyDynamicProxy(MyService target) {
this.target = target;
}
public Object invoke(Object obj, Method method, Object[] args) throws Exception {
System.out.println("MyDynamicProxy invoke method: " + method.getName());
return method.invoke(target, args);
}
}
public class MyProxy {
private InvocationHandler handler;
private MyService service;
public MyProxy(MyService service) {
this.service = service;
this.handler = new MyDynamicProxy(service);
}
public MyService getProxy() {
return (MyService) Proxy.newProxyInstance(Proxy.classLoader(), service.getClass().getInterfaces(), handler);
}
}

3. CGLIB动态代理

CGLIB动态代理是基于Java类的字节码生成技术实现的动态代理。与JDK动态代理不同的是,CGLIB动态代理不需要目标对象实现特定的接口,而是直接基于目标对象的类进行动态代理。这种方式的优势是可以代理任何目标对象,而不仅仅是接口定义的对象。

例如,可以通过CGLIB动态代理实现对MyServiceImpl类的动态代理:

public class MyServiceImpl {
public void doSomething() {
System.out.println("MyServiceImpl doSomething()");
}
public void doSomethingElse() {
System.out.println("MyServiceImpl doSomethingElse()");
}
}
public class MyDynamicProxy implements MethodInterceptor {
private MyServiceImpl target;
public MyDynamicProxy(MyServiceImpl target) {
this.target = target;
}
public Object intercept(Method method, Method proceed, Object[] args) throws Exception {
System.out.println("MyDynamicProxy intercept method: " + method.getName());
return proceed.invoke(target, args);
}
}
public class MyProxy {
private MethodInterceptor interceptor;
private MyServiceImpl service;
public MyProxy(MyServiceImpl service) {
this.service = service;
this.interceptor = new MyDynamicProxy(service);
}
public MyServiceImpl getProxy() {
return (MyServiceImpl) Proxy.create(MyServiceImpl.class, interceptor);
}
}

转载地址:http://evvfk.baihongyu.com/

你可能感兴趣的文章
Oracle创建用户、角色、授权、建表
查看>>
Oracle创建用户与授予表空间与权限
查看>>
oracle删除重复数据保留第一条记录
查看>>
Oracle发布VirtualBox 7.1稳定版!支持ARM、优化了UI、支持Wayland等
查看>>
oracle启动关闭服务,启动关闭oracle服务.bat
查看>>
Oracle命令行创建数据库
查看>>
Oracle和SQL server的数据类型比较
查看>>
oracle在日本遇到的技术问题
查看>>
oracle基础 管理索引
查看>>
oracle如何修改单个用户密码永不过期
查看>>
oracle字符集
查看>>
Oracle学习
查看>>
oracle数据库笔记---oracleweb视图使用流程,及plsql安装
查看>>
Transformer 架构解释
查看>>
Oracle数据库表空间 数据文件 用户 以及表创建的SQL代码
查看>>
Oracle数据库验证IMP导入元数据是否会覆盖历史表数据
查看>>
Oracle未开启审计情况下追踪表变更记录
查看>>
Oracle查看数据库会话连接
查看>>
oracle树形查询 start with connect by
查看>>
oracle毕业论文题目,历届毕业论文申报题目大全.doc
查看>>