Java-spring-@Aspect-@Before-注解实现

本文详细介绍了如何在Spring框架中创建一个Maven项目,并利用AspectJ进行AOP编程。首先,展示了如何添加JUnit和Spring的相关依赖,接着定义了一个接口及其实现类。然后,创建了一个切面类,使用@Aspect和@Before注解实现前置通知功能,用于在业务方法执行前打印日志信息。最后,通过JUnit测试类验证了切面功能的正确性,测试输出显示日志信息在目标方法执行前被打印。
摘要由CSDN通过智能技术生成

1. 创建maven项目

<!-- 添加依赖 -->
    <dependencies>
        <!-- 单元测试依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!--   spring 依赖     -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
        <!--  aspects 框架依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
    </dependencies>

2. 创建普通类接口并实现该类

// 普通类的接口
package org.example;

public interface SomeService {
    public void doSome(String name, int age);
}

// 接口实现
package org.example.impl;

import org.example.SomeService;
import org.springframework.stereotype.Component;

/**
 * 目标类
 */
@Component("mySomeServiceImpl") // <bean id="mySomeServiceImpl" class="org.example.impl.SomeServiceImpl">
public class SomeServiceImpl implements SomeService {
    @Override
    public void doSome(String name, int age) {
        System.out.println("doSome is used....");
    }
}

3. 实现切面(用于增强业务功能)

// 切面类
package org.example;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * MyAspectJ => 增强功能
 *
 * @Aspect: 是 aspectj 框架中的注解
 * 作用: 表示当前类是切面类
 * 切面类: 是用来给业务方法增加功能的类,在这个类中有切面的功能代码
 * 位置: 在类定义的上面
 */
@Component("myAspectj") // <bean id="myAspectj" class=" org.example.MyAspectJ">
@Aspect
public class MyAspectJ {
    /**
     * 定义方法,方法是实现切面功能的
     * 方法的定义要求:
     *  1. 公共方法 public
     *  2. 方法没有返回值
     *  3. 方法名称自定义
     *  4. 方法可以有参数,也可以没有参数
     *      如果有参数,参数不是自定义的,有几个参数类型可以使用
     */

    /**
     * @Before: 前置通知注解
     * 属性: value,是切入点表达式,表示切面的功能执行的位置
     * 位置: 在方法上面
     * 特点:
     * 1. 在目标方法之前先执行
     * 2. 不会改变目标方法的执行结果
     * 3. 不会影响目标方法的执行
     */
    @Before("execution(public void org.example.impl.SomeServiceImpl.doSome(String,int))")
    public void doLog() {
        // 切面的功能代码
        System.out.println("日志信息.....");
    }
}

4. 测试功能

package org.example;

import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Unit test for simple AspectJ.
 */
public class TestAspectJBefore {
    /**
     * 测试 aspectJ 的 Before(前置通知)
     */
    @Test
    public void testAspectjBefore() {
        // 获取配置文件路径
        String config = "aspectj_before/aspectj_before.xml";
        // 创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        // 生成代理对象
        SomeService proxy = (SomeService) ac.getBean("mySomeServiceImpl");
        // 通过代理对象执行方法,实现目标方法执行时,增强了功能
        proxy.doSome("coder-itl", 18);
    }
}

5. 配置文件信息

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--  声明组件扫描器  -->
    <context:component-scan base-package="org.example"/>

    <!--
     声明自动代理生成器: 使用 aspectj 框架内部的功能,创建目标对象的代理对象
     创建代理对象是在内存中实现的,修改目标对象的内存中的结构
     构建为代理对象,所以目标对象就是被修改后的代理对象
     -->
    <aop:aspectj-autoproxy/>

</beans>

6. 测试输出

AspectJ Before
AspectJ Before
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值