首页 > 基础资料 博客日记

【JAVA篇】------ spring aop

2025-01-02 03:00:08基础资料围观48

文章【JAVA篇】------ spring aop分享给大家,欢迎收藏Java资料网,专注分享技术知识


AOP(面向切面编程)

💬欢迎交流:在学习过程中如果你有任何疑问或想法,欢迎在评论区留言,我们可以共同探讨学习的内容。你的支持是我持续创作的动力!
👍点赞、收藏与推荐:如果你觉得这篇文章对你有所帮助,请不要忘记点赞、收藏,并分享给更多的小伙伴!你们的鼓励是我不断进步的源泉!
🚀推广给更多人:如果你认为这篇文章对你有帮助,欢迎分享给更多对写作感兴趣的朋友,让我们一起进步,共同提升!

前言

AOP(面向切面编程)是一种通过分离横切关注点(如日志、事务、安全等)来增强程序模块化的编程范式。在Java中,AOP通常通过Spring等框架实现,通过切面将附加功能插入到业务逻辑中,减少代码冗余,提高可维护性。
本文我们主要来介绍AOP:

一、AOP的概念
  1. 定义
    AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,其主要思想是将一些跨越多个模块的功能(例如日志记录、安全验证、事务处理等)从主要的业务逻辑中提取出来。通过在程序运行时,将这些额外的代码(切面)巧妙地插入到目标对象的方法调用中,从而增强方法功能。

  2. 与OOP的对比
    面向对象编程(OOP)关注的是将数据和操作数据的逻辑封装到对象中,通过继承和多态等特性构建软件系统。而AOP则专注于处理分散在多个对象和方法中的横切关注点。例如,在一个复杂的Java企业级应用中,如果每个业务方法都需要记录日志,使用OOP会导致日志记录代码的重复,维护困难。AOP能够将日志记录功能提取出来,集中管理,避免代码重复。


二、AOP的核心概念
  1. 切面(Aspect)
    切面是将横切关注点抽象出来的一种模块。它包含通知(Advice)和切点(Pointcut)。切面定义了在哪些连接点(切点)执行哪些增强逻辑(通知)。例如,日志记录的切面定义了在哪些方法执行前后记录日志。

  2. 通知(Advice)
    通知是切面在目标方法执行时的具体增强逻辑。Java AOP中有五种通知类型:

    • 前置通知(Before Advice):在目标方法执行之前执行。
    • 后置通知(After Advice):在目标方法正常结束后执行。
    • 返回通知(After-Returning Advice):目标方法返回值之后执行。
    • 异常通知(After-Throwing Advice):目标方法抛出异常时执行。
    • 环绕通知(Around Advice):可以在目标方法执行前后加入自定义逻辑,甚至控制是否调用目标方法。
  3. 切点(Pointcut)
    切点用于定义通知的应用位置,通常通过切点表达式来指定。连接点是程序执行过程中的特定位置(如方法调用)。通过切点,可以确定在哪些连接点插入切面。

  4. 连接点(Join Point)
    连接点是程序执行过程中的一个位置,例如方法的调用、方法的执行等。在AOP中,切面代码会在这些连接点处进行织入。

  5. 织入(Weaving)
    织入是将切面应用到目标对象的过程,生成一个新的代理对象。Java中有不同的织入方式:编译时织入、类加载时织入、运行时织入。Spring AOP采用的是运行时织入,通过动态代理(JDK动态代理或CGLIB)将切面织入目标对象。


三、AOP在Java中的应用场景
  1. 日志记录
    AOP可用于在多个业务方法前后记录日志,而不需要在每个业务方法中重复编写日志记录代码。比如在Spring Web应用中,可以用AOP切面统一记录控制器方法的日志。

  2. 事务管理
    在企业级应用中,事务管理是重要的横切关注点。AOP可以用来在多个数据库操作方法之间自动开始、提交或回滚事务。例如,在Spring的业务层方法中,通过AOP配置事务切面,确保数据库操作的事务一致性。

  3. 安全检查
    AOP可以用于在方法执行前检查用户权限。比如,在某些资源管理系统中,通过AOP切面检查当前用户是否有权限执行某些敏感操作。


四、租房场景下的代理模式相关代码实现

1. 整体介绍

在找中介租房的场景中,可以使用代理模式来实现相关功能。这个场景涉及到租房接口、被代理对象(房东)、代理对象(中介)以及调用者(租客)。同时,探讨静态代理模式和动态代理模式(JDK动态代理)的实现及其优缺点。

2. 静态代理模式
  1. 抽象方法
package cn.icss.proxy;

public interface ZuFang {
    void zuFang();
}
  1. 被代理对象(房东)
package cn.icss.proxy;

public class FangDong implements ZuFang {
    @Override
    public void zuFang() {
        System.out.println("图书馆向外出租500W一年");
    }
}
  1. 代理对象(中介)
package cn.icss.proxy;

/**
 * @author yishu
 * @create 2024-12-23 9:28
 * 代理对象
 */
public class ZhongJie implements ZuFang {
    private String which;

    public String getWhich() {
        return which;
    }

    public void setWhich(String which) {
        this.which = which;
    }

    FangDong zhangsan = new FangDong();
    FangDong2 lisi = new FangDong2();

    @Override
    public void zuFang() {
        System.out.println("向我们收取中介费");
        if (which.equals("图书")) {
            zhangsan.zuFang();
        } else if (which.equals("演示")) {
            lisi.zuFang();
        }
        System.out.println("向房东收取介绍费");
        System.out.println("定期换床单20块");
    }
}
  1. 调用者
package cn.icss.proxy;

public class WoMen {
    public static void main(String[] args) {
        ZhongJie xiaowang = new ZhongJie();
        xiaowang.setWhich("演示");
        xiaowang.zuFang();
    }
}
  1. 静态代理模式缺点
    当被代理对象数量增加时,代理代码会变得非常冗长,需要增加大量判断,降低代码的可维护性。

3. 动态代理模式(JDK动态代理)
  1. 修改后的代理对象
package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ZhongJie implements InvocationHandler {
    private Object fangDong;

    public Object getFangDong() {
        return fangDong;
    }

    public void setFangDong(Object fangDong) {
        this.fangDong = fangDong;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("向租客收取介绍费");
        Object result = method.invoke(fangDong, args);
        System.out.println("向房东收取介绍费");
        return result;
    }
}
  1. 测试(调用者)
package proxy;

import java.lang.reflect.Proxy;

public class WoMen {
    public static void main(String[] args) {
        ZhongJie xiaowang = new ZhongJie();
        FangDong2 lisi = new FangDong2();
        xiaowang.setFangDong(lisi);
        
        ZuFang zuFang = (ZuFang) Proxy.newProxyInstance(
            WoMen.class.getClassLoader(), 
            new Class[]{ZuFang.class}, 
            xiaowang
        );
        
        zuFang.zuFang();
    }
}

总结

AOP在Java开发中应用广泛,特别是在处理日志、事务、安全等横切关注点时,能够显著提高代码的复用性和可维护性。同时,代理模式作为一种设计模式,在租房场景中,静态代理和动态代理各有优缺点。通过动态代理可以减少代码的冗余,提高代码的扩展性和灵活性。


文章来源:https://blog.csdn.net/2302_79751907/article/details/144729825
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云