【JAVA】Spring AOP 介绍与简单DEMO

Spring AOP 介绍与简单DEMO

通知(Advice)

Spring中的切面一共提供5种通知的类型:
  前置通知(@Before)
  后置通知(@After)
  返回通知(@AfterReturning)
  异常通知(@AfterThrowing)
  环绕通知(@Around)
前面4个较为容易理解,例如“前置通知”,我们通常在一个方法的第一句打印出传入的方法参数,此时就可以使用前置通知在方法调用前打印出传入的参数。对于“后置通知”实际是“返回通知”和“异常通知”的并集,返回通知表示程序正确运行返回后执行,异常通知表示程序不正常运行抛出异常时执行,而后置通知则不论程序是否正确运行,一旦离开方法就会执行。
环绕通知最为强大,它包裹了被通知的方法,可同时定义前置通知和后置通知。

切点(Pointcut)

通知定义了何时工作以及工作内容,切点则定义了在何处工作,也就是在哪个方法应用通知。要表达出在哪个方法中运用通知,这需要用到切点表达式。Spring AOP借助AspectJ(另一种AOP实现)的切点表达式来确定通知被应用的位置,虽然是借助但并不支持所有AspectJ的所有切点指示器而仅仅是其一个子集,这其中最为常用的就是execution切点指示器,表示执行。例如:

execution(* com.deo.springaop.Test.test(..))

DEMO

1. 引用依赖
1) 需要引用的AOP依赖:
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjrt</artifactId>
		<version>1.8.10</version>
	</dependency>
	<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjweaver</artifactId>
		<version>1.8.10</version>
	</dependency>
2) 需要引用的测试依赖:
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.3.7.RELEASE</version>
			<scope>test</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.3.7.RELEASE</version>
		</dependency>
2. Spring 配置自动扫描
3. 定义一个业务类DEMO:
package aop.service;

import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;

@Component
public class AuthService {

	public boolean delete(JSONObject s) {
		System.out.println("-- delete : " + s);
		return false;
	}
}
4. 针对此业务类定义一个切面:
@Aspect
@Component
public class AopUtil {

	@AfterReturning(returning = "res", pointcut = "execution(* aop.service.*.delete(..))")
	public void check(JoinPoint joinPoint, boolean res) {
		System.out.println("-- check -- param: " + joinPoint.getArgs() + " -- res: " + res);
		Object objArr[] = joinPoint.getArgs();
		for(Object obj : objArr) {
			System.out.println("-- param: " + obj.toString());
		}
	}
}

也可以写成:

@Aspect
@Component
public class AopUtil {

	@Pointcut("execution(* aop.service.*.delete(..))")
	public void pointcut() {
		System.out.println("-- pointcut --");
	}
	
	@AfterReturning(value = "pointcut()", returning = "res")
	public void check(JoinPoint joinPoint, boolean res) {
		System.out.println("-- check -- param: " + joinPoint.getArgs() + " -- res: " + res);
  String className = joinPoint.getTarget().getClass().getName();
  String methodName = joinPoint.getSignature().getName();
  Object objArr[] = joinPoint.getArgs();
		for(Object obj : objArr) {
			System.out.println("-- param: " + obj.toString());
		}
	}
}

@AfterReturning:定义在方法返回时执行此切面。
@Pointcut:定义了一个切点,execution 标识在哪些方法会触发此切点。
returning:可以获取方法返回的参数.
JoinPoint joinPoint: 通过此对象可以获取方法的信息以及入参参数。

5. 测试类:
package aop.test;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import com.alibaba.fastjson.JSONObject
import aop.service.AuthService;

@RunWith(SpringRunner.class)
@ContextConfiguration(locations = {"classpath*:applicationContext.xml"})
public class Test {

	@Autowired
	private AuthService auth;
	
	@org.junit.Test
	public void delete() {
		JSONObject json = new JSONObject();
		json.put("name", "张三");
		json.put("age", "17");
		auth.delete(json);
	}
}
6. 运行结果:
-- delete : {"age":"17","name":"张三"}
-- check -- param: [Ljava.lang.Object;@76b1e9b8 -- res: false
-- param: {"age":"17","name":"张三"}

结果表明在执行业务类的delete方法之后,执行了切面的check方法。

AOP编程可以运用在日志、事务、权限控制等等一些地方,只要你想。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值