spring AOP

JoinPoint 对象
连接点,Spring AOP 的JoinPoint就是对这个连接点的抽象,Spring中接入点一般是方法。
@Before(value = "@annotation(com.changhong.yyhl.spider.worker.aop.SpiderParam)")
public void param(JoinPoint joinPoint){
   // JoinPoint 就是连接点方法的抽象,可以操作被增强位置的信息
}

JoinPoint 可得到:
被代理对象方法的参数、方法签名、返回值等信息
Object[] args = joinPoint.getArgs();
可以拿到目标对象的方法参数,这时对args的修改,就会真正的修改到真实切点方法的参数上去

JoinPoint 的增强类 => ProceedingJoinPoint
ProceedingJoinPoint pjp 配合@Around使用环绕,可以在增加方法中使用pjp.proceed()分割目标方法的 before 和 after,
.proceed()执行是把控制权交给了目标方法。
.proceed()之前执行的代码是前置增强,
.proceed()之后执行的代码是后置增强。


定位织入点位置
(1)基于注解
(2)
@Pointcut(
"execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?.name-pattern(param-pattern)throws-pattern?)"
)

modifier-pattern:表示方法的修饰符
ret-type-pattern:表示方法的返回值
declaring-type-pattern?:表示方法所在的类的路径
name-pattern:表示方法名
param-pattern:表示方法的参数
throws-pattern:表示方法抛出的异常
&&符号表示与关系,使用||表示或关系、使用!表示非关系
bean()描述符,是spring bean的name

解释:
其中后面跟着“?”的是可选项。
在各个pattern中,可以使用"*"来表示匹配所有。
在param-pattern中,可以指定具体的参数类型,多个参数间用“,”隔开,各个也可以用“*”来表示匹配任意类型的参数,如(String)表示匹配一个String参数的方法;(*,String)表示匹配有两个参数的方法,第一个参数可以是任意类型,而第二个参数是String类型。
可以用(..)表示零个或多个任意的方法参数。

例子:
excecution(* com.tianmaying.service.BlogService.updateBlog(..))  and bean('tianmayingBlog')

定义增强方法
@Before:前置通知,在调用目标方法之前执行通知定义的任务
@After:后置通知,在目标方法执行结束后,无论执行结果如何都执行通知定义的任务
@After-returning:后置通知,在目标方法执行结束后,如果执行成功,则执行通知定义的任务
@After-throwing:异常通知,如果目标方法执行过程中抛出异常,则执行通知定义的任务
@Around:环绕通知,在目标方法执行前和执行后,都需要执行通知定义的任务

@Before(value = "controllerAspect()")
public void methodBefore(JoinPoint joinPoint){
       // 执行增强方法
}

最后“定义增强方法”和“定位织入点位置”需要放到一个类中,使用@Aspect和@Compent注解


基于自定义注解@SpiderParam的例子
1 定义注解
@Target(ElementType.METHOD)//这个注解是应用在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface SpiderParam { }

2 定义切面对象
@Aspect
@Component// 切面对象任然是个对象,故扫描 public class SpiderParamAspect { private static final Logger logger = LoggerFactory.getLogger(SpiderParamAspect.class); // 通过注解来确定切点位置

    @Before(value = "@annotation(com.changhong.yyhl.spider.worker.aop.SpiderParam)")
    public void param(JoinPoint joinPoint) throws Throwable{

        Object[] args = joinPoint.getArgs();//  下面都是增强方法,这个可以捕捉到被代理对象的参数列表
        Param param = null;
        for (Object arg : args){
            if(arg instanceof Param){
                param = (Param) arg;// 找到我们需要的预处理的参数对象
            }
        }
        if(param == null){
            return;
        }
        // 操作param就可以达到预处理被代理对象方法的目的
        param.setXXX()
    }
}

3 注解了@SpiderParam到方法被增强

4 如果在增强方法中想要取注解值

//这个注解是应用在方法上
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Permission {
  String value();
}

@Aspect
@Component
public class PermissionAspect {

    // 定义基于注解的切点
    @Pointcut(value = "@annotation(com.changhong.touchc.core.component.auth.Permission)")
    public void pointCut(){}

    // 绑定切点和注解,&&后面小写打头的permission
    @Before(value = "pointCut() && @annotation(permission)")
    public void doBefore(JoinPoint joinPoint, Permission permission) {
          String permissionValue = permission.value();
     }
}

@Permission("employeeCapacity:view")
@RequestMapping(value = "/pageInfoEmployeeInfo",method = RequestMethod.GET)
ResponseEntity getEmployeeInfo(){

}

基于@Pointcut和@Before
@Before的value值应该是@Pointcut注解的方法签名

@Pointcut("execution(......)")
void pointcutAspect()

@Before(value = "pointcutAspect()")
public void param(JoinPoint joinPoint){}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值