Spring-06 Xml和注解方式配置Aop

本文详细介绍了如何在Spring中配置AOP,包括XML方式和注解方式。首先,从基本环境准备开始,涉及导入依赖和添加XML约束。接着,详细讲解了Spring的五种通知类型,并在XML配置中展示了如何针对这些通知类型进行增强类配置。最后,转向注解方式配置AOP,涵盖了核心配置、目标类与增强类的包扫描、切入点表达式以及其他相关注解的使用,同时提供了测试环节以验证配置的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本环境准备

导入依赖

<!-- https://mvnrepository.com/artifact/aspectj/aspectjrt -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.6</version>
</dependency>

添加xml 新约束

在 spring 核心配置文件中添加 aop 约束

<?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:p="http://www.springframework.org/schema/p"
	   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
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
	
</beans>

Spring的 五种通知类型

通知类型标签标签
前置通知aop:before目标方法执行前增强
后置通知aop:after目标方法执行后增强
环绕通知aop:around目标方法执行前后都增强
返回通知aop:after-returning目标方法成功执行之后调用
异常通知aop:after-throwing在目标方法抛出异常后调用

XML 方式配置AOP

根据五种通知类型 配置增强类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class SelectAdvice {

    public void before(JoinPoint joinPoint){
        System.out.println("前置");
        System.out.println("目标类是: "+ joinPoint.getTarget());
        System.out.println("被织入的目标类方法为: "+ joinPoint.getSignature().getName());
    }

    public void afterReturning(){
        System.out.println("后置(方法不出现异常时调用! )");
    }

    public void around(ProceedingJoinPoint pjp) {
        System.out.println("环绕前置");
        try {
            // ProceedingJoinPoint 是joinpoint 的子接口, 用于执行目标方法, 确定在环绕通知中的位置
            pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("环绕后置");
    }

    public void exception(){
        System.out.println("异常通知");
    }

    public void after(){
        System.out.println("最终通知(类似于异常处理机制中的 finally)");
    }

}

xml配置

<!--配置目标类-->
<bean id="select" class="cn.Select"/>
<!--配置增强类(切面类)-->
<bean id="selectAdvice" class="cn.SelectAdvice"/>

<!-- 配置SpringAOP 增强 -->
<aop:config>
<!--     要对 哪些方法进行增强  -->
    <aop:pointcut id="abc" expression="execution(* cn..*.*(..))"/>
    <aop:pointcut id="def" expression="execution(* cn..*.update*(..))"/>
<!--    增强类的方法, 都对应那种增强方式    -->
    <aop:aspect ref="selectAdvice">
        <aop:before method="before" pointcut-ref="abc"/>
        <aop:after-returning method="afterReturning" pointcut-ref="abc"/>
        <aop:around method="around" pointcut-ref="abc"/>
        <aop:after-throwing method="exception" pointcut-ref="abc"/>
        <aop:after method="after" pointcut-ref="abc"/>
    </aop:aspect>
</aop:config>

测试

public static void main(String[] args) {
    ClassPathXmlApplicationContext app =
            new ClassPathXmlApplicationContext("classpath:application_context.xml");
    Select select =
            (Select)app.getBean("select");
    select.select();

}

基于注解方式配置 AOP

核心配置文件扫描目标类和增强类所在包

<!-- 使用注解配置 bean  -->
<context:component-scan base-package="cn.aop"/>
<!-- 加载 aop 的 注解 -->
<aop:aspectj-autoproxy/>

目标类添加注解

@Component

增强类配置(切面)

切入点表达式

// 声明增强类
@Aspect
@Component

@Pointcut("execution(* cn..*.select(..))")
    private void abc(){
    }

    @Pointcut("execution(* cn..*.update(..))")
    private void def(){
    }

其他注解

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class SelectAdvice {
    @Pointcut("execution(* cn..*.select(..))")
    private void abc(){
    }

    @Pointcut("execution(* cn..*.update(..))")
    private void def(){
    }

    @Before("abc()")
    public void before(JoinPoint joinPoint){
        System.out.println("前置");
        System.out.println("目标类是: "+ joinPoint.getTarget());
        System.out.println("被织入的目标类方法为: "+ joinPoint.getSignature().getName());
    }

    @AfterReturning("abc()")
    public void afterReturning(){
        System.out.println("后置(方法不出现异常时调用! )");
    }

    @Around("abc()")
    public void around(ProceedingJoinPoint pjp) {
        System.out.println("环绕前置");
        try {
            // ProceedingJoinPoint 是joinpoint 的子接口, 用于执行目标方法, 确定在环绕通知中的位置
            pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("环绕后置");
    }

    @AfterThrowing("abc()")
    public void exception(){
        System.out.println("异常通知");
    }
    @After("abc()")
    public void after(){
        System.out.println("最终通知(类似于异常处理机制中的 finally)");
    }

}

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations ={"classpath:application_context.xml"})
public class Test1 {

    @Autowired
    Select select;

    @Test
    public void aopTest(){
        select.add();
    }

}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值