Spring的AOP中2个重要的注解
AOP中2个重要的注解
@Aspect
/**
* Aspect declaration
*
* @author Alexandre Vasseur
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Aspect {
/**
* @return the per clause expression, defaults to singleton aspect.
* Valid values are "" (singleton), "perthis(...)", etc
*/
public String value() default "";
}
说明:
作用:
声明当前类是一个切面类。
属性:
value:
默认我们的切面类应该为单例的。但是当切面类为一个多例类时,指定预
处理的切入点表达式。
用法是perthis(切入点表达式)。
它支持指定切入点表达式,或者是用@Pointcut修饰的方法名称(要求全限定方法名)
使用场景:
此注解也是一个注解驱动开发aop的必备注解。
示例:
Component
@Scope("prototype")//注意:通常情况下我们的切面类是不需要多例的。
@Aspect("perthis(execution(* com.dalianpai.service.impl.*.*(..)))")
public class LogUtil {
/**
* 用于配置当前方法是一个前置通知
*/
@Before("execution(* com.dalianpai.service.impl.*.*(..))")
public void printLog(){
System.out.println("执行打印日志的功能");
}
}
如果是多例模式,就要用perthis不然会报错,而且是当都有表达式的时候,切面上的表达式生效
@Pointcut
源码:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Pointcut {
/**
* The pointcut expression
* We allow "" as default for abstract pointcut
*/
String value() default "";
/**
* When compiling without debug info, or when interpreting pointcuts
at runtime,
* the names of any arguments used in the pointcut are not available.
* Under these circumstances only, it is necessary to provide the arg
names in
* the annotation ‐ these MUST duplicate the names used in the
annotated method.
* Format is a simple comma‐separated list.
*/
String argNames() default "";
}
说明:
作用:
此注解是用于指定切入点表达式的。
属性:
value:
用于指定切入点表达式。表达式的配置详解请参考第五章节第三小节《切
入点表达式的写法》
argNames:
用于指定切入点表达式的参数。参数可以是execution中的,也可以是args中的。通常情况下不使用此属性也可以获得切入点方法参数。
使用场景:
在实际开发中,当我们的多个通知需要执行,同时增强的规则确定的情况下,就可以把切入点表达式通用化。此注解就是代替xml中的<aop:pointcut>标签,实现切入点表达式的通用化。
实列:
@Component
@Aspect
public class LogUtil {
/**
* 通用切入点表达式
* 在value属性的中使用了&&符号,表示并且的关系。
* &&符号后面的args和execution一样,都是切入点表达式支持的关键字,表示匹配参数。指定的内容
* 可以是全限定类名,或者是名称。当指定参数名称时,要求与方法中形参名称相同。
* argNames属性,是定义参数的名称,该名称必须和args关键字中的名称一致。
*/
@Pointcut(value = "execution(* com.dalianpai.service.impl.*.*(com.dalianpai.domain.User))&& args(user)",argNames = "user")
private void pt1(User user){}
}
@Pointcut(value = "execution(* com.dalianpai.spring5.aop.service.impl.*.saveUser(..)) && args(user)")
private void pointcut1(User user){};
/**
* 用于配置当前方法是一个前置通知
*/
@Before(value = "pointcut1(user)",argNames = "user")
public void printLog(User user){
System.out.println("执行打印日志的功能"+user);
}
当然也可以把切入点的方法单独提取出来也没有问题,不一定要在切面中