Spring AOP 面向切面复习

GitHub地址:https://github.com/binlian/binglian-AOP

AOP是什么?

1.一种编程范式,不是编程语言

2.解决特定问题,不是解决所有问题

3.OOP的补充,不是替代

 

AOP初衷

代码重复性

水平分离:展示层->服务处->持久层

垂直分离:模块划分(订单、库存等)

切面分离:分离功能性需求与非功能性需求

 

使用AOP的好处

集中处理某一关注点/横切逻辑

可以很方便地添加/删除关注点

侵入性少,增强代码可读性及可维护性

 

aop应用场景,权限控制,缓存控制,事务控制,审计日志,性能监控,分布式追踪,异常处理

 

 

@Aspect要切面的类的注解 配置

@Pointcut 切入选择那个类。方法或者其他进行切入

@Advice 切面时间 在什么时段进行 之前还是之后

advice 有五种

 

 

 

 

 

切面表达式

designators指示器

wildcards通配符 *匹配任意数量的字符、+匹配指定类及其子类、..一般用于匹配任意的子包或参数

Operators运算符 &&与操作符、||或操作符、!非操作符

 

三种配合使用

 

 

 

 

 

 

匹配方法

那个包下的犯法


 //匹配任何公共方法
 @Pointcut("execution(public * com.binglian.service.*.*(..))")

 //匹配com.binglian包及子包下Service类中无参方法
 @Pointcut("execution(* com.binglian..*Service.*())")

 //匹配com.binglian包及子包下Service类中的任何只有一个参数的方法
 @Pointcut("execution(* com.binglian..*Service.*(*))")

 //匹配com.binglian包及子包下任何类的任何方法
 @Pointcut("execution(* com.binglian..*.*(..))")

 //匹配com.binglian包及子包下返回值为String的任何方法
 @Pointcut("execution(String com.binglian..*.*(..))")

 //匹配异常
 execution(public * com.binglian.service.*.*(..) throws java.lang.IllegalAccessException)


//例子
 @Pointcut("execution(public * com.binglian.service..*Service.*(..) throws java.lang.IllegalAccessException)")
 public void matchCondition(){}

 @Before("matchCondition()")
 public void before(){
  System.out.println("");
  System.out.println("###before");
 }

它拦截的是有抛出异常的方法,就是匹配异常

在异常方法之前输出###before

 

 

匹配包

within匹配那个报下的方法

//匹配ProductService类里头的所有方法
@Pointcut("within(com.binglian.service.ProductService)")
//匹配com.imooc包及子包下所有类的方法
@Pointcut("within(com.binglian..*)")

 

 

匹配注解

com.binglian.anno.AdminOnly 这个是自定义的注解 然后找到那个包所有犯法进行匹配


 //匹配方法标注有AdminOnly的注解的方法
@Pointcut("@annotation(com.binglian.anno.AdminOnly) && within(com.binglian..*)")
//匹配标注有NeedSecured的类底下的方法 //class级别
@Pointcut("@within(com.binglian.anno.NeedSecured) && within(com.binglian..*)")
//匹配标注有NeedSecured的类及其子类的方法 //runtime级别
在spring context的环境下,二者没有区别
@Pointcut("@target(com.binglian.anno.NeedSecured) && within(com.binglian..*)")
//匹配传入的参数类标注有Repository注解的方法
@Pointcut("@args(com.binglian.anno.NeedSecured) && within(com.binglian..*)")




	@Pointcut("@annotation(com.binglian.anno.NeedSecured) && within(com.binglian..*)")
	public void matchAnno(){}

	
	@Before("matchAnno()")
	public void before(){
		System.out.println("");
		System.out.println("###before");
	}

 

匹配参数

匹配方法里的参数

args相对于execution简单多了

匹配任何以find开头而且只有一个Long参数的方法
@Pointcut("execution(* *..find*(Long))")
匹配任何以find开头的而且第一个参数为Long型的方法
@Pointcut("execution(* *..find*(Long,...))")
匹配任何只有一个Long参数的方法
@Pointcut("args(Long) && within(com.binglian..*)")
匹配第一个参数为Long型的方法
@Pointcut("args(Long,..) && within(com.binglian..*)")

匹配的对象

this 拦截

target 不拦截

bean 是所有的方法

//匹配AOP对象的目标对象为指定类型的方法,即LogService的aop代理对象的方法
@Pointcut("this(com.imooc.log.Loggable)")
//匹配实现Loggable接口的目标对象(而不是aop代理后的对象)的方法
@Pointcut("target(com.imooc.log.Loggable)")
//this 可以拦截 DeclareParents(Introduction)
//target 不拦截 DeclareParents(Introduction)
//匹配所有以Service结尾的bean里头的方法
@Pointcut("bean(*Service)")


 

Advice注解

package com.binglian.config;

import static org.hamcrest.CoreMatchers.nullValue;

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.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AdviceAspectConfig {

	
	@Pointcut("@annotation(com.binglian.anno.AdminOnly) && within(com.binglian..*)")
	public void matchAnno(){}
	
	
	@Pointcut("execution(* *..find*(Long)) && within(com.binglian..*)")
	public void matchLongArg(){}
	
	
	@Pointcut("execution(public * com.binglian.service..*Service.*(..) throws java.lang.IllegalAccessException) && within(com.binglian..*)")
    public void matchException(){}
	
	@Pointcut("execution(String com.binglian..*.*(..)) && within(com.binglian..*)")
    public void matchReturn(){}
	
	
	
	/************advice**************/

	
//	@After("matchAnno()")
//	public void after(){
//		System.out.println("###after");
//	}
	
//	@AfterThrowing("matchException()")
//	public void after(){
//		System.out.println("###after");
//	}
	
//	@AfterReturning(value="matchReturn",returning="result")
//	public void after(Object result){
//		System.out.println("###after returning"+result);
//	}
	
	
	@Around("matchAnno()")
	public Object after(ProceedingJoinPoint joinPoint){
		System.out.println("###before");
		Object result=null;
		try{
			result=joinPoint.proceed();
		}catch (Throwable e){
			System.out.println("###ex");
		}finally{
			System.out.println("###finally");
		}
		
		return result;
	}
	
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值