在非Spring项目中实现AOP

概要

在非Spring项目中实现AOP(面向切面编程)可以使用AspectJ,这是一个强大的AOP框架,独立于Spring运行。AspectJ允许你在Java程序中通过编译期或运行时插入横切关注点(cross-cutting concerns)。

下面是一个使用AspectJ在非Spring项目中实现切面的示例:

步骤:

添加依赖

如果你使用的是Maven项目,在pom.xml中添加AspectJ的依赖:

<dependencies>
    <!-- AspectJ runtime dependency -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.9.7</version>
    </dependency>
    <!-- AspectJ weaver dependency -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.7</version>
    </dependency>
</dependencies>

创建目标类

创建一个需要切面的目标类

package com.example;

public class MyService {
    public void performTask() {
        System.out.println("Performing task...");
    }
}

创建切面类

创建一个切面类,并使用AspectJ注解来定义切点和通知。

package com.example;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MyAspect {

    @Before("execution(* com.example.MyService.performTask(..))")
    public void beforeTask() {
        System.out.println("Before performing task...");
    }

    @After("execution(* com.example.MyService.performTask(..))")
    public void afterTask() {
        System.out.println("After performing task...");
    }
}

配置AspectJ

在项目的根目录下创建一个名为aop.xml的配置文件,用于配置AspectJ的织入。

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <aspects>
        <aspect name="com.example.MyAspect"/>
    </aspects>
    <weaver>
        <include within="com.example..*"/>
    </weaver>
</aspectj>

运行代码

创建一个主类来运行代码,并启用AspectJ的织入器

package com.example;

import org.aspectj.weaver.loadtime.WeavingURLClassLoader;

public class Main {
    public static void main(String[] args) {
        // Load AspectJ runtime
        WeavingURLClassLoader loader = new WeavingURLClassLoader(
            Main.class.getClassLoader(), 
            Main.class.getClassLoader().getURLs()
        );

        try {
            // Use the AspectJ weaving class loader to load the service class
            Class<?> clazz = loader.loadClass("com.example.MyService");
            Object service = clazz.getDeclaredConstructor().newInstance();
            clazz.getMethod("performTask").invoke(service);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

解释:

  • @Aspect注解表示这个类是一个切面。
  • @Before注解表示在目标方法执行之前执行的通知。
  • @After注解表示在目标方法执行之后执行的通知。
  • execution(* com.example.MyService.performTask(..))定义了切点表达式,表示MyService类中的performTask方法。
  • aop.xml配置文件用于定义哪些切面和目标类需要被AspectJ织入。

execution表达式用法

在AspectJ中,execution表达式可以指定一个包下的多个类和方法。你可以使用通配符来匹配多个类和方法。下面是一些常见的用法示例:

匹配一个包下的所有类的所有方法

@Before("execution(* com.example..*.*(..))")
public void beforeAnyMethod() {
    System.out.println("Before any method in com.example or its subpackages...");
}

这表示匹配com.example包及其所有子包中的所有类的所有方法。

匹配一个包下的所有类中某些特定的方法

@Before("execution(* com.example..*.perform*(..))")
public void beforePerformMethods() {
    System.out.println("Before any method starting with 'perform' in com.example or its subpackages...");
}

这表示匹配com.example包及其所有子包中的所有类中,以perform开头的方法。

匹配一个包下的特定类的所有方法

@Before("execution(* com.example.MyService.*(..))")
public void beforeMyServiceMethods() {
    System.out.println("Before any method in com.example.MyService...");
}

这表示匹配com.example包中的MyService类的所有方法。

匹配一个包下的特定类中的特定方法

@Before("execution(* com.example.MyService.performTask(..))")
public void beforePerformTask() {
    System.out.println("Before performTask method in com.example.MyService...");
}

这表示匹配com.example包中的MyService类的performTask方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值