SpringAOP之helloworld

本文介绍了一个使用Spring AOP实现的日志记录案例。通过定义切入点、通知类型和切面类,展示了如何对目标方法进行增强,包括前置通知、后置通知、环绕通知等。

新建javaProject,导入相关jar包

com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.1.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar


新建一个类HelloWorld.java

package cn.baokx.spring.aop.helloworld;

import org.springframework.stereotype.Component;

@Component
public class HelloWorld {
	public int divide(int i,int j){
		return i/j; 
	}
}

添加Spring配制文件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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	<!-- 配置自动扫描的包 -->
	<context:component-scan base-package="cn.baokx.spring.aop.helloworld"></context:component-scan>

	<!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

新建一个切面LoggingAspect.java

package cn.baokx.spring.aop.helloworld;

import java.util.Arrays;
import java.util.List;

import org.aspectj.lang.JoinPoint;
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.core.annotation.Order;
import org.springframework.stereotype.Component;

//把类交由IOC容器管理且声明为一个切面
@Component
@Aspect
//切面的优先级,值越小,优先级越高 
@Order(1)
public class LoggingAspect {
	
	//切入点表达式
	@Pointcut("execution(public int cn.baokx.spring.aop.helloworld.HelloWorld.divide(int,int))")
	public void declareJointPointExpression(){}
	
	//声明为前置通知:在目标方法开始之前执行
	@Before("declareJointPointExpression()")
	public void beforeMethod(JoinPoint joinPoint){
		String methodName = joinPoint.getSignature().getName();
		List<Object> args = Arrays.asList(joinPoint.getArgs());
		System.out.println("The method " + methodName + " begins with "+ args);
	}
	
	//目标方法正常结束后执行
	@AfterReturning(value="declareJointPointExpression()"
			,returning="result")
	public void afterReturning(JoinPoint joinPoint,Object result){
		String methodName = joinPoint.getSignature().getName();
		System.out.println("The method " + methodName + " ends with " + result);
	}
	
	//目标方法出现异常时执行
	//可以访问到异常对象,可在出现特定异常时执行
	@AfterThrowing(value="declareJointPointExpression()"
			,throwing="exception")
	public void aferThrowing(JoinPoint joinPoint,Exception exception){
		String methodName = joinPoint.getSignature().getName();
		System.out.println("The method " + methodName + " occurs " + exception);
	}
	
	//声明为后置通知:在目标方法执行之后(无论是否发生异常)执行
	//后置通知中不能访问到目标方法执行的结果
	@After("declareJointPointExpression()")
	public void afterMethod(JoinPoint joinPoint){
		String methodName = joinPoint.getSignature().getName();
		System.out.println("The method " + methodName + " ends ");
	}
	
	//环绕通知要携带ProceedingJoinPoint类型的参数
	//环绕通知类似于动态代理的全过程,可实现其它通知
	//环绕通知必须有返回值,即目标方法的返回值
	@Around("declareJointPointExpression()")
	public Object arouncMethod(ProceedingJoinPoint pjd){
		Object result = null;
		String methodName = pjd.getSignature().getName();
		//执行目标方法
		try {
			//前置通知
			System.out.println("The method " + methodName + " begins with "+ Arrays.asList(pjd.getArgs()));
			result = pjd.proceed();
			//返回通知
			System.out.println("The method " + methodName + " ends with " + result);
		} catch (Throwable e) {
			//异常通知
			System.out.println("The method " + methodName + " occurs " + e);
			throw new RuntimeException(e);
		}
		//后置通知
		System.out.println("The method " + methodName + " ends ");
		return result;
	}

}


创建Main.java类进行测试
package cn.baokx.spring.aop.helloworld;

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

public class Main {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");
		int result = helloWorld.divide(10, 2);
		result = helloWorld.divide(10, 0);
	}
}



转载于:https://my.oschina.net/u/1427708/blog/710611

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值