Spring—AspectJ注解实现通知

 

1. 在Spring中启用AspectJ注解支持步骤如下:

  • 要在Spring应用中使用AspectJ注解,必须在classpath下包含AspectJ类库:aopalliance.jar, aspectj.weaver.jarspring-aspects.jarspring-aop.jar
  • 将aop Scema添加到<beans>根元素中
  • 要在Spring IOC容器中启用AspectJ注解支持,只要在Bean配置文件中定义一个空的XMl元素<aop:aspectj-autoproxy>
  • 当Spring IOC容器侦测到Bean配置文件中的<aop:aspectj-autoproxy>元素时,会自动为与AspectJ切面匹配的Bean创建代理

2. 实现前置日志

新建Calculator接口:

public interface Calculator {
	
	int add(int i, int j);
	int sub(int i, int j);
	
	int mul(int i, int j);
	int div(int i, int j);
}

新建一个CalculatorImpl类实现该接口:

import org.springframework.stereotype.Component;

@Component
public class CalculatorImpl implements Calculator {

	@Override
	public int add(int i, int j) {
		int result = i + j;
		return result;
	}

	@Override
	public int sub(int i, int j) {
		int result = i - j;
		return result;
	}

	@Override
	public int mul(int i, int j) {
		int result = i * j;
		return result;
	}

	@Override
	public int div(int i, int j) {
		int result = i / j;
		return result;
	}

}

再新建一个LoggingAspect类来实现日志:

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

//把这个类声明为一个切面:需要把该类放入到IOC容器中,再声明为一个切面
@Aspect
@Component
public class LoggingAspect {
	//声明该方法是一个前置通知:在目标方法开始之间执行
	@Before("execution(public int impl.Calculator.add(int, int))")
	public void beforeMethod() {
		System.out.println("The method begins");
	}
}

其中“@Component”这个注解是把该类放入到IOC容器中,“@Aspect”这个借口是将其声明为一个切面。二者共同将该类声明为一个切面。“@Before”这个注解是声明“beforeMethod”这个方法是一个前置通知,在“public int impl.Calculator.add(int, int))”这个方法前执行。

然后配置applicationContext.xml文件:

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

	<!-- 配置自动扫描的包 -->
	<context:component-scan base-package="impl"></context:component-scan>
	
	<!-- 是AspectJ注解起作用:自动为匹配的类生成代理效果 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

再在Main中调用方法:

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

public class Main {
	
	public static void main(String[] args) {
		
		//1.创建Spring的IOC容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationcontext.xml");
		
		//2.从IOC容器中获取Bean的实例
		Calculator calculator = ctx.getBean(Calculator.class);
		
		//3.使用bean
		int result = calculator.add(3, 6);
		System.out.println("result:" + result);
	}
}

最后得到结果如下图所示:

可以看到“The method begins”这个日志就自己自动输出了。

3. 后置通知

有了前置通知之后,后置通知的实现就很简单了,与前置通知类似,只需在目标方法前加入“@After”注解即可:

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

//把这个类声明为一个切面:需要把该类放入到IOC容器中,再声明为一个切面
@Aspect
@Component
public class LoggingAspect {
	//声明该方法是一个前置通知:在目标方法开始之间执行
	@Before("execution(public int impl.Calculator.add(int, int))")
	public void beforeMethod() {
		System.out.println("The method begins");
	}

	@After("execution(public int impl.Calculator.add(int, int))")
	public void afterMethod() {
		System.out.println("The method ends");
	}
}

其余配置与前置通知一样

4. 返回通知

与前置通知类似,只需在目标方法前加入“@AfterReturning”注解即可

	@AfterReturning(value = "execution(public int impl.Calculator.*(int, int))", returning = "result")
	public void afterReturningMethod(JoinPoint joinpoint, Object result) {
		
		String methodName = joinpoint.getSignature().getName();
		System.out.println("The method "+ methodName + " ends with " + result);
	}

5. 异常通知

与前置通知类似,只需在目标方法前加入“@AfterThrowing”注解即可

	@AfterThrowing(value = "execution(public int impl.Calculator.*(int, int))", throwing = "ex")
	public void afterThrowingMethod(JoinPoint joinpoint, Exception ex) {
		
		String methodName = joinpoint.getSignature().getName();
		System.out.println("The method "+ methodName + " occurs excetion " + ex);
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值