一:自定义注解知识点:
- 没有定义成员变量的定义。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceLimit {
}
@Target表示应用范围,作用域。
@Retention 表示作用时间长短。
- 有定义成员变量的定义
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceType {
/**
* 服务表id
* @return
*/
int value();
/**
* 服务名称
* @return
*/
String name();
}
二:切面类定义:
- 例子如下
@Aspect@Slf4j@Componentpublicclass SysPlatLogAspect {/ 指定切面/@Pointcut(“execution(public com.rest.module...(..))”)publicvoid getMethods() {}/ 指定注解*/@Pointcut(“@annotation(com.rest.utils.SysPlatLog)”)publicvoid withAnnotationMethods() {}
@Pointcut(“within(net.deniro.spring4.aspectj.)”)
privatevoidmethod1() {
}
/**
切点被命名为 method2,且该切点可以在本类或子孙类中使用
/
@Pointcut(“within(net.deniro.spring4.aspectj.)”)
protectedvoidmethod2() {
}
/*
切点被命名为 method3,且该切点可以在任何类中使用
这里还使用了复合运算
/
@Pointcut(“method1() && method2()”)
publicvoidmethod3() {
}
}
@Aspect 是切面类注解,表示该类是切面类。
@Component 把这个类做为实例,注入Ioc容器。
切点pointcut类型:execution,annotation,within
execution,泛指类型。
annatation,具体的,某一个
within,范围
[
](https://blog.csdn.net/wangmx1993328/article/details/108164388)
三:实际的应用场景:
@Aspect:作用是把当前类标识为一个切面供容器读取@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。@Around:环绕增强,相当于MethodInterceptor @AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行 @Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有@AfterThrowing:异常抛出增强,相当于ThrowsAdvice@After: final增强,不管是抛出异或者正常退出都会执行
@Aspect
@Order(value = 999)
@Component
public class AspectHelloWorld {
/
@Pointcut :切入点声明,即切入到哪些目标方法。value 属性指定切入点表达式,默认为 “”。
用于被下面的通知注解引用,这样通知注解只需要关联此切入点声明即可,无需再重复写切入点表达式
切入点表达式常用格式举例如下:
- com.wmx.aspect.EmpService.(..)):表示 com.wmx.aspect.EmpService 类中的任意方法
- com.wmx.aspect..(..)):表示 com.wmx.aspect 包(不含子包)下任意类中的任意方法
- com.wmx.aspect...(..)):表示 com.wmx.aspect 包及其子包下任意类中的任意方法
/
@Pointcut(value = “execution( com.wmx.aspect.EmpServiceImpl.*(..))”)
private void aspectPointcut() {
}
/
前置通知:目标方法执行之前执行以下方法体的内容。
value:绑定通知的切入点表达式。可以关联切入点声明,也可以直接设置切入点表达式
@param joinPoint:提供对连接点处可用状态和有关它的静态信息的反射访问
Object[] getArgs():返回此连接点处(目标方法)的参数
Signature getSignature():返回连接点处的签名。
Object getTarget():返回目标对象
Object getThis():返回当前正在执行的对象
StaticPart getStaticPart():返回一个封装此连接点的静态部分的对象。
SourceLocation getSourceLocation():返回与连接点对应的源位置
String toLongString():返回连接点的扩展字符串表示形式。
String toShortString():返回连接点的缩写字符串表示形式。
String getKind():返回表示连接点类型的字符串
/
@Before(value = “aspectPointcut()”)
public void aspectBefore(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
Signature signature = joinPoint.getSignature();
Object target = joinPoint.getTarget();
Object aThis = joinPoint.getThis();
JoinPoint.StaticPart staticPart = joinPoint.getStaticPart();
SourceLocation sourceLocation = joinPoint.getSourceLocation();
String longString = joinPoint.toLongString();
String shortString = joinPoint.toShortString();
System.out.println(“【前置通知】”);
System.out.println(“\targs=” + Arrays.asList(args));
System.out.println(“\tsignature=” + signature);
System.out.println(“\ttarget=” + target);
System.out.println(“\taThis=” + aThis);
System.out.println(“\tstaticPart=” + staticPart);
System.out.println(“\tsourceLocation=” + sourceLocation);
System.out.println(“\tlongString=” + longString);
System.out.println(“\tshortString=” + shortString);
}
/
后置通知:目标方法执行之后执行以下方法体的内容,不管目标方法是否发生异常。
value:绑定通知的切入点表达式。可以关联切入点声明,也可以直接设置切入点表达式
*/
@After(value = “aspectPointcut()”)
public void aspectAfter(JoinPoint joinPoint) {
System.out.println(“【后置通知】”);
System.out.println(“\tkind=” + joinPoint.getKind());
}
/
返回通知:目标方法返回后执行以下代码
value 属性:绑定通知的切入点表达式。可以关联切入点声明,也可以直接设置切入点表达式
pointcut 属性:绑定通知的切入点表达式,优先级高于 value,默认为 “”
returning 属性:通知签名中要将返回值绑定到的参数的名称,默认为 “”
@param joinPoint :提供对连接点处可用状态和有关它的静态信息的反射访问
@param result :目标方法返回的值,参数名称与 returning 属性值一致。无返回值时,这里 result 会为 null.
/
@AfterReturning(pointcut = “aspectPointcut()”, returning = “result”)
public void aspectAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println(“【返回通知】”);
System.out.println(“\t目标方法返回值=” + result);
}
/*
异常通知:目标方法发生异常的时候执行以下代码,此时返回通知不会再触发
value 属性:绑定通知的切入点表达式。可以关联切入点声明,也可以直接设置切入点表达式
pointcut 属性:绑定通知的切入点表达式,优先级高于 value,默认为 “”
throwing 属性:与方法中的异常参数名称一致,
@param ex:捕获的异常对象,名称与 throwing 属性值一致
/
@AfterThrowing(pointcut = “aspectPointcut()”, throwing = “ex”)
public void aspectAfterThrowing(JoinPoint jp, Exception ex) {
String methodName = jp.getSignature().getName();
System.out.println(“【异常通知】”);
if (ex instanceof ArithmeticException) {
System.out.println(“\t【” + methodName + “】方法算术异常(ArithmeticException):” + ex.getMessage());
} else {
System.out.println(“\t【” + methodName + “】方法异常:” + ex.getMessage());
}
}
}
链接切入点介绍