Spring入门_AspectJ

本文介绍如何在Spring框架中使用@AspectJ实现面向切面编程(AOP),包括配置@AspectJ、定义切入点(pointcut)、组合pointcut、各种通知(advice)的使用示例,以及一个完整的Spring配置和测试案例。

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

Spring中配置@AspectJ

对@AspectJ支持可以使用XML或java风格的配置

确保AspectJ的aspectjweaver.jar库包含在应用程序(版本1.6.8或更高版本)的classpath中

aspect

@AspectJ切面使用@Aspect注解配置,拥有@Aspect的任何bean将被Spring自动识别并应用

用@Aspect注解的类可以有方法和字段,他们也可能包括切入点(pointcout),通知(Advice)和引入(introduction)声明

@Aspect注解是不能够通过类路径自动检测发现的,所以需要配合使用@component注释或者在xml配置bean

一个类中的@Aspect注解标识它为一个切面,并且将自己从自动代理中排除。


pointcut

一个切入点通过一个普通的方法定义来提供,并且切入点表达式使用@Pointcut注解,方法返回类型必须为void
定义一个名为‘anyOldTransfer’,这个切入点将匹配任何名为"transfer"的方法的执行


组合pointcut

切入点表达式可以通过&&、||和!进行组合,也可以通过名字引用切入点表达式

通过组合,可以建立更加复杂的切入点表达式


定义良好的pointcuts

AspectJ是编译期的AOP

检查代码并匹配连接点与切入点的代价是昂贵的

一个好的切入点应该包括以下几点

-选择特定类型的连接点,如execution,get,set,call,handler

-确定连接点范围,如:winthin,withincode

-匹配上下文信息,如:this,target,@annotation



After returning advice

方法结束后执行

After(finally)advice

最终通知必须准备处理正常和异常俩种返回情况,它通常用于释放资源


Around avice

环绕通知使用@Around注解来声明,通知方法的第一个参数必须是ProceedingJoinPoint类型

在通知内部调用ProceedingJoinPoint的proceed()方法会导致执行真正的方法,传入一个Object[]对象,数组中的值将被作为参数传递给方法

例子:

配置:

<?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
		 http://www.springframework.org/schema/context/spring-context-4.2.xsd
		 http://www.springframework.org/schema/aop
		 http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		 ">
		
		<context:component-scan base-package="com.txr.AspectJ"/>
		<aop:aspectj-autoproxy/>
</beans>

AspectEX类

package com.txr.AspectJ;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;


@Component
@Aspect
public class AspectEx {
	@Pointcut("execution(* com.txr.AspectJ.*Biz.*(..))")
	public void pointcut(){}
	
	@Pointcut("within(com.txr.AspectJ.*)")
	public void bizPointcut(){}
	
	//@Before("pointcut()")
	@Before("execution(* com.txr.AspectJ.*Biz.*(..))")
	public void before()
	{
		System.out.println("Before");
	}
	
	@AfterReturning(pointcut="bizPointcut()",returning="returnValue")
	public void afterReturning(Object returnValue){
		System.out.println("AfterReturning : "+returnValue);
	}
	@AfterThrowing(pointcut="pointcut()",throwing="e")
	public void afterThrowing(RuntimeException e)
	{
		System.out.println("AfterThrowing : "+e.getMessage());
	}
	
	@After("pointcut()")
	public void after()
	{
		System.out.println("After");
	}
	@Around("pointcut()")
	public Object around(ProceedingJoinPoint pjp) throws Throwable
	{
		System.out.println("Around 1.");
		Object obj=pjp.proceed();
		System.out.println("Around 2.");
		System.out.println("Around : "+obj);
		return obj;
		
	}
}

TxrBiz类

package com.txr.AspectJ;


import org.springframework.stereotype.Service;


@Service
public class TxrBiz {
	public String save(String arg)
	{
		System.out.println("TxrBiz save:"+arg);
		//throw new RuntimeException("这是个异常");
		return "Save success!";
	}
}

测试类:

package AutoWiring;

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

import com.txr.AspectJ.TxrBiz;

public class TestAspect {
	private ApplicationContext context=null;
	@Before
	public void init(){
		context=new ClassPathXmlApplicationContext("com/txr/resource/spring-ioc.xml");
	}
	@Test
	public void test()
	{
		TxrBiz biz=(TxrBiz) context.getBean("txrBiz");
		biz.save("txr");
	}
}

测试结果:

Around 1.
Before
TxrBiz save:txr
Around 2.
Around : Save success!
After
AfterReturning : Save success!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值