spring aop 学习

spring aop 学习

1.匹配包、类型

//匹配ProductService类里头的所有方法
@pointcut("within(com.imooc.service.ProductService)")
public void matchType(){}

//匹配com.imooc包及子包下所有类的方法
@poincut("within(com.imooc..*)")
public void matchType(){}

2.匹配对象

/*
* public class DemoDao implements IDao{}
*/
//匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法
@pointcut("this(com.imooc.DemoDao)")
public void thisDemo(){}

//匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法
@pointcut"target(com.imooc.IDao)"public void targetDemo(){}

//匹配所有以Service结尾的bean里头的方法
@pointcut("bean(*Service)")
public void beanDemo(){}

3.参数匹配

//匹配任何以find开头而且只有一个Long参数的方法
@pointcut("execution(* *..find*(Long))")
public void argsDemo1(){}

//匹配任何只有一个Long参数的方法
@pointcut("args(Long)")
public void argsDemo2(){}

//匹配任何以find开头的而且第一个参数为Long型的方法
@pointcut("execution(* *.find*(Long,..))")
public void argsDemo3(){}

//匹配第一个参数为Long型的方法
@pointcut("args(Long,..)")
public void argsDemo4(){}

@pointcut("args(Long,..) && within(com.imooc.service.*)")
public void argsDemo4(){}

4.匹配注解

//匹配方法标注有AdminOnly的注解的方法
@pointcut("@annotation(com.imooc.demo.security.AdminOnly)")
public void annoDemo(){}

//匹配标注有Beat的类的底下的方法,要求的annotation的RetentionPolicy级别为Class
@pointcut("within(com.google.common.annotations.Beat)")
public void annoWithinDemo(){}

//匹配注有Repository的类底下的方法,要求的annotation的RetentionPolicy级别为RUNTIME
@pointcut("@target(org.springframework.stereotype.Repository)")
public void annoTargetDemo(){}

//匹配传入的参数类标注有Repository注解的方法
@poincut("args(org.springframework.stereotype.Repository)")
public void annoArgsDemo(){}

5种Advice注解
  1. @Before,前置通知

  2. @After(finally),后置通知,方法执行完之后

  3. @AfterReturning,返回通知,成功执行之后

  4. @AfterThrowing,异常通知,抛出异常之后

  5. @Around,环绕通知

注意事项:
1、不宜把重要的业务逻辑放到aop中处理
2、无法拦截static、final方法和private方法
3、spring aop 是无法拦截内部调用的。

例如:下面这段代码在第二次调用getMenuList是无法从缓存中获取,因为此时的this不是经过aop代理的bean。

//下面这段代码在第二次调用getMenuList是无法从缓存中获取
@Component
public class MenuService {

    @Cacheable(cacheNames = {"menu"})
    public List<String> getMenuList(){
        System.out.println("");
        System.out.println("mock:get from db");
        return Arrays.asList("article","comment","admin");
    }

    public List<String> getRecommends(){
		return this.getMenuList();
    }
}

//可以将代码改为从代理Bean对象调用

//1.获取从spring代理的bean
@Component
public class ApplicationContextHolder implements ApplicationContextAware {

    private static ApplicationContext ctx;

    public static ApplicationContext getContext() {
        return ctx;
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ctx = applicationContext;
    }
}
2.//使用代理对象解决内部调用
@Component
public class MenuService {
    @Cacheable(cacheNames = {"menu"})
    public List<String> getMenuList(){
        System.out.println("");
        System.out.println("mock:get from db");
        return Arrays.asList("article","comment","admin");
    }
    public List<String> getRecommends(){
        MenuService proxy = ApplicationContextHolder.getContext().getBean(MenuService.class);
        return proxy.getMenuList();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值