博客
关于我
Spring篇-AOP
阅读量:146 次
发布时间:2019-02-27

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

AOP(面向切面编程)是一种软件开发的编程范式,旨在通过动态代理和切面技术,隔离系统中的关注点,提升系统的可维护性和可扩展性。AOP通过在不修改源代码的情况下,动态地在主干功能中注入新的功能,降低了代码之间的耦合度,提高了开发效率。

AOP的概念

AOP的核心思想是通过在业务逻辑的各个部分(即切面)中插入额外的逻辑(通知),从而实现对系统流程的监控、记录或修改。这种方式使得代码的耦合度降低,系统的可维护性提高,开发效率也随之提升。

AOP的通俗描述是:在不修改现有代码的情况下,通过动态方式在主干功能中注入新功能。这意味着可以在不影响现有业务逻辑的情况下,添加日志记录、事务管理、权限验证等功能。

AOP底层原理

AOP的实现通常依赖于动态代理技术。动态代理在Java中有两种实现方式:

  • 基于接口的动态代理(JDK动态代理):适用于目标对象实现了接口的情况。Java的Proxy类提供了newProxyInstance方法来创建动态代理对象。这种方式通过生成一个代理类,代理目标对象的方法调用。

  • 基于类的动态代理(CGLIB动态代理):适用于目标对象没有接口的情况。CGLIB动态代理通过生成一个继承目标类的子类来实现动态代理。

  • JDK动态代理代码实现

    在实际开发中,JDK动态代理是最常用的实现方式。以下是使用JDK动态代理实现AOP的一种常见做法:

    代码实现

    public interface UserDao {    int add(int a, int b);    String update(String id);}public class UserDaoImpl implements UserDao {    @Override    public int add(int a, int b) {        System.out.println("执行了add方法");        return a + b;    }    @Override    public String update(String id) {        System.out.println("执行了update方法");        return id;    }}public class JDKProxyTest {    public static void main(String[] args) {        Class[] interfaces = {UserDao.class};        UserDao dao = (UserDao) Proxy.newProxyInstance(            JDKProxyTest.class.getClassLoader(),            interfaces,            new UserDaoProxy(new UserDaoImpl())        );        System.out.println(dao.add(10, 20));        System.out.println("---------------------------------------------");        System.out.println(dao.update("cVzhanshi"));    }}public class UserDaoProxy implements InvocationHandler {    private Object obj;    public UserDaoProxy(Object obj) {        this.obj = obj;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)        throws Throwable {        System.out.println("方法之前执行...." + method.getName() + " :传递的参数... " + Arrays.toString(args));        Object res = method.invoke(obj, args);        System.out.println("方法之后执行...." + obj);        return res;    }}

    运行效果

    运行上述代码,可以看到输出结果如下:

    方法之前执行....add :传递的参数... [10, 20]执行了add方法11方法之后执行....UserDaoImpl@16:29----------------------------------------------方法之前执行....update :传递的参数... [cVzhanshi]执行了update方法cVzhanshi方法之后执行....UserDaoImpl@16:29

    AOP术语

    在AOP中,主要涉及以下术语:

  • 连接点:系统中能够被增强的方法或代码位置。

  • 切入点:实际被增强的方法或代码位置。

  • 通知:在增强的逻辑中,用于实现特定功能的代码块。通知有多种类型:

    • 前置通知:在方法执行前调用。
    • 后置通知:在方法执行后调用(返回通知)。
    • 最终通知:在方法执行后总是调用。
    • 异常通知:在方法抛出异常时调用。
    • 环绕通知:在方法执行前后都有逻辑。
  • 切面:指将通知应用到切入点的过程。

  • AOP操作

    在实际项目中,Spring框架通常基于AspectJ实现AOP操作。AspectJ是一个独立的AOP框架,与Spring无关,但常常与Spring一起使用。

    基于注解的AOP操作

    在使用AspectJ实现AOP时,主要使用以下注解:

  • @Before:表示前置通知。
  • @AfterReturning:表示返回通知。
  • @After:表示最终通知。
  • @AfterThrowing:表示异常通知。
  • @Around:表示环绕通知。
  • 以下是一个简单的示例:

    public class User {    public void add() {        System.out.println("执行add方法");    }}public class UserProxy {    @Before(value = "execution(*User.add())")    public void before() {        System.out.println("方法执行前....");    }    @After(value = "execution(*User.add())")    public void after() {        System.out.println("方法执行后....");    }    @Around(value = "execution(*User.add())")    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {        System.out.println("环绕前....");        proceedingJoinPoint.proceed();        System.out.println("环绕后....");    }}

    在Spring中配置:

    配置文件实现

    在Spring的配置文件中,可以通过 <aop:config>标签来配置切面。以下是一个简单的示例:

    补充

  • 相同切入点抽取:当多个增强类使用相同的切入点时,可以通过创建公共切入点方法来提高代码复用性。

  • 切面优先级:在多个增强类中定义相同的切入点时,可以通过在增强类上添加@Order注解来设置优先级,优先级越小的切面优先生效。

  • 通过以上方法,开发者可以灵活地使用AOP技术来实现系统的各项需求,提升系统的可维护性和扩展性。

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

    你可能感兴趣的文章
    MySQL高级-视图
    查看>>
    nacos集群搭建
    查看>>
    Nessus漏洞扫描教程之配置Nessus
    查看>>
    Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
    查看>>
    Netpas:不一样的SD-WAN+ 保障网络通讯品质
    查看>>
    Netty WebSocket客户端
    查看>>
    Netty工作笔记0011---Channel应用案例2
    查看>>
    Netty工作笔记0014---Buffer类型化和只读
    查看>>
    Netty工作笔记0050---Netty核心模块1
    查看>>
    Netty工作笔记0084---通过自定义协议解决粘包拆包问题2
    查看>>
    Netty常见组件二
    查看>>
    netty底层源码探究:启动流程;EventLoop中的selector、线程、任务队列;监听处理accept、read事件流程;
    查看>>
    Netty核心模块组件
    查看>>
    Netty框架的服务端开发中创建EventLoopGroup对象时线程数量源码解析
    查看>>
    Netty源码—2.Reactor线程模型一
    查看>>
    Netty源码—4.客户端接入流程一
    查看>>
    Netty源码—4.客户端接入流程二
    查看>>
    Netty源码—5.Pipeline和Handler一
    查看>>
    Netty源码—6.ByteBuf原理二
    查看>>
    Netty源码—7.ByteBuf原理三
    查看>>