• Spring AOP


    目录

    Spring AOP的主要组成部分

    一个简单的Spring AOP示例

    JDK 动态代理和 CGLIB 代理

    JDK动态代理:

    CGLIB动态代理:

    Spring AOP 和 AspectJ AOP

    Spring AOP:

    AspectJ AOP:

    总结



    AOP是Aspect-Oriented Programming(面向方面编程或面向切面)的简称,是一种编程范式,用于增强、扩展和管理应用程序的功能。它通过将交叉关注点(Cross-Cutting Concerns)从应用程序的主要业务逻辑中分离出来,实现了更好的模块化和可维护性。交叉关注点通常包括日志记录、事务管理、安全性、异常处理等方面的功能。AOP的核心思想是通过切面(Aspect)将这些关注点模块化,然后在应用程序的不同部分插入切面,以实现统一的行为。

    Spring AOP的主要组成部分
    1. 切面(Aspect): 切面是一个模块化单元,它定义了要在应用程序中的哪些位置(连接点)进行什么操作(通知)。切面通常包括通知和切点。

    2. 通知(Advice): 通知是切面的实际行为,它定义了在什么时候、在连接点的哪个位置,执行什么操作。Spring AOP支持以下几种通知类型:

      • 前置通知(Before Advice):在连接点之前执行。

      • 后置通知(After Advice):在连接点之后执行(无论连接点是否抛出异常)。

      • 返回通知(After Returning Advice):在连接点正常返回后执行。

      • 异常通知(After Throwing Advice):在连接点抛出异常后执行。

      • 环绕通知(Around Advice):在连接点之前和之后执行,可以控制连接点的执行。

    3. 切点(Pointcut): 切点是在应用程序中定义的一组连接点的集合,它决定了在哪里应用通知。通知会在切点匹配的连接点上执行。

    4. 连接点(Join Point): 连接点是应用程序执行的特定点,通常是方法的执行。通知可以插入连接点的位置。

    5. 引入(Introduction): 引入允许您向现有的类添加新方法和属性。

    6. 目标对象(Target Object): 目标对象是被切面通知的实际对象,它可能是应用程序中的任何Bean。

    7. 代理对象(Proxy Object): 代理对象是应用程序中的目标对象的代理,它可以截获对目标对象的方法调用,并在调用前后执行通知。

    一个简单的Spring AOP示例

    1.项目中添加Spring AOP相关的依赖。

            
                org.springframework.boot
                spring-boot-starter-aop
                5.3.27
            

    2.创建一个目标类(Target Class),这是我们将应用AOP的类。

    public class MyService {
        public void showTime() {
            System.out.println("Now :" + new Date(System.currentTimeMillis()));
        }
    ​
        public void sayHi() {
            System.out.println("Hi");
        }
    }

    3.创建一个切面类(Aspect Class),这是我们的AOP切面。

    @Aspect
    public class LoggerAspect {
        public final static Logger logger = LoggerFactory.getLogger(LoggerAspect.class);
    ​
        /**
         * MyService类作为切点
         */
        @Pointcut("execution(* com.elaine.myspring.aop.service.MyService.*(..))")
        public void myLogger(){}
    ​
    ​
        @Before("myLogger()")
        public void doBefore() {
            logger.info("Before PointCut, say Hello!");
        }
    ​
        @After("myLogger()")
        public void doAfter() {
            logger.info("After PointCut, say Bye!");
        }
    }

    4.配置文件配置AOP

    
    
    ​
        
        
        
        
        
        
    

    5.调用方法

    public class MySpringApplication {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
            MyService service = (MyService) applicationContext.getBean("myService");
            service.showTime();
            service.sayHi();
        }
    }

    结果

    JDK 动态代理和 CGLIB 代理

    Spring AOP使用过动态代理实现的,而说到动态代理,主要有JDK 动态代理和 Cglib 动态代理。

    JDK动态代理:
    1. 基于接口: JDK动态代理要求目标对象实现一个或多个接口,代理对象会实现这些接口。

    2. 使用java.lang.reflect.Proxy类: JDK动态代理使用Java标准库中的 java.lang.reflect.Proxy 类来创建代理对象。

    3. 只能代理接口中定义的方法: JDK动态代理只能代理接口中定义的方法,不能代理目标类中的非接口方法。

    4. 更安全: 由于基于接口,JDK动态代理在安全性方面更可靠,因为它不允许代理非接口方法。

    5. 适用于有接口的类: 如果目标对象实现了接口,JDK动态代理是一个好的选择。

    6. 性能稍低: 由于代理对象要实现接口中的所有方法,JDK动态代理的性能相对较低。

    JDK的动态代理相当给力,一句话就OK了:

    Java提供了java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现动态代理。

    public class RpcClientProxy {
        public  T clientProxy(final Class interfaceCls, final String host, final int port) {
           return (T) Proxy.newProxyInstance(interfaceCls.getClassLoader(), new Class[]{interfaceCls}, new RemoteInvocationHandler(host, port));
        }
    }
    CGLIB动态代理:
    1. 基于类: CGLIB动态代理不要求目标对象实现接口,它可以代理普通Java类。

    2. 使用字节码技术: CGLIB动态代理使用字节码技术来生成代理类,而不是java.lang.reflect.Proxy

    3. 可以代理类的所有方法: CGLIB动态代理可以代理目标类中的所有方法,包括非接口方法。

    4. 更强大: 由于可以代理类的所有方法,CGLIB动态代理更灵活和强大。

    5. 适用于没有接口的类: 如果目标对象没有实现接口,或者你需要代理类的非接口方法,CGLIB动态代理是一个好的选择。

    6. 性能相对较高: 由于可以直接代理类的方法,CGLIB动态代理的性能通常比JDK动态代理略高。

    Spring AOP 和 AspectJ AOP

    Spring AOP和AspectJ AOP都是用于实现面向切面编程(AOP)的框架,但它们有一些重要的差异:

    Spring AOP:
    1. 纯Java实现: Spring AOP是纯Java实现的AOP框架,它使用代理模式来实现AOP。它通过代理对象包装目标对象,然后在代理对象上应用切面逻辑。

    2. 基于代理: Spring AOP主要基于代理,它可以使用JDK动态代理或CGLIB代理,具体取决于目标对象是否实现接口。

    3. 局部AOP支持: Spring AOP支持细粒度的AOP,可以选择在需要的类和方法上应用切面,从而实现局部AOP。

    4. 配置驱动: Spring AOP通常通过XML配置、注解或Java配置来定义切面和通知,并将其应用到Bean上。

    5. 对Spring框架集成友好: Spring AOP紧密集成在Spring框架中,可以轻松使用Spring容器管理Bean和依赖注入。

    AspectJ AOP:
    1. 独立框架: AspectJ是独立的AOP框架,它不依赖于Spring或其他容器。它可以单独使用或与Spring集成。

    2. 全功能AOP: AspectJ提供了更丰富的AOP功能,可以应用于类、方法、字段等各个层面。它支持更多种类的通知(如环绕通知、引入通知等)。

    3. 编译时和运行时: AspectJ可以在编译时织入切面逻辑,也可以在运行时织入。这使得它更强大和灵活。

    4. 全局AOP: AspectJ通常会在整个应用程序中应用切面,而不仅仅局限于某些类或方法。

    5. 基于注解或XML配置: AspectJ可以通过注解或XML配置来定义切面和通知,类似于Spring AOP。

    总结
    • Spring AOP是一个轻量级的AOP框架,主要用于与Spring容器集成,适用于需要局部AOP的应用。

    • AspectJ AOP是一个功能强大的独立AOP框架,可以用于任何Java应用,它提供更丰富的AOP功能和更灵活的织入方式。你可以根据项目的需求选择使用Spring AOP、AspectJ AOP,或两者结合使用。在某些情况下,AspectJ AOP可能更适合复杂的AOP需求。

  • 相关阅读:
    【Linux】屏蔽项目服务非正常日志输出到message文件中
    21组Midjourney绘画关键词,专为游戏设计的奇异生物的盛宴
    中创算力:打造区块链产业生态,助力郑州创建国家级区块链先导区​
    APP专项测试方法和工具的使用(测试新手必看)
    UnityEditor编辑器扩展-表格功能
    华为OD机考算法题:机器人活动区域
    Ubuntu安装中文man手册
    解决计算机丢失msvcr71.dll问题,总结5种解决方法分享
    云原生Devops 的实现方法
    OSI七层模型与TCP/IP四层模型
  • 原文地址:https://blog.csdn.net/Elaine2391/article/details/133818265