请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

SpringAOP之使用切入点创建通知

[复制链接]
查看: 16|回复: 0

1万

主题

2万

帖子

4万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
47993
发表于 2019-12-4 02:16 | 显示全部楼层 |阅读模式
之前已经说过了SpringAOP中的几种看护典范以及怎样建立简单的看护看法点
一、什么是切入点

经过之前的例子中,我们可以建立ProxyFactory的方式来建立看护,然后获得目标类中的方式。经过不同典范的看护,能对这些方式做差此外事。可是,这类方式会对全部类中的全数方式都有感化,可是很多时候我们只想对这个类中的部分方式举行看护处置惩罚,那就要利用切入点来正确地控制到特定的方式

  • 也就是说,我们的切入点就是用来肯定一个类中的方式(正确到方式),类似于界说一些法则一样,来找到和这个法则相婚配的类,晓得这一点,往下看就轻易多了。
二、切入点的分类

在Spring中的要建立切入点时,就要实现Pointcut类。
  1. package org.springframework.aop;public interface Pointcut{    ClassFilter getClassFilter();    MethodMatcher getMethodMacher();}
复制代码
以上两个方式返回的类的源码以下:

  • ClassFilter
  1. package org.springframework.aop;/***   这是一个函数式接口,就是传入一个类,*   假如这个类满足我们的要求,就返回true*   也就是说这个切入点适用于这个类(也就是这个类不婚配我们的法则)*/@FunctionalInterfacepublic interface ClassFilter {    boolean matches(Class var1);}
复制代码

  • MethodMatcher
  1. package org.springframework.aop;import java.lang.reflect.Method;/***   这个固然就是用来婚配方式了,*   有两种典范,静态和静态,这个由isRuntime()的返回值来决议,true就是静态,false就是静态。这个典范就是决议了这个切入点是静态的还是静态的*   */public interface MethodMatcher {    MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;    //用于静态婚配,就是和方式的参数无关    boolean matches(Method var1, Class var2);    boolean isRuntime();    //用于静态婚配,也就是和方式的参数有关,由于参数是会变的    boolean matches(Method var1, Class var2, Object... var3);}
复制代码
综上,切入点分为两种,静态切入点和静态切入点,静态切入点要每次检查方式的实参能否是满足要求,这会发生额外的开支。假如可以,假如可以,尽大要利用静态切入点。
三、切入点的八个实现类

实现类描摹org.springframework.aop.support.annotation.AnnotationMatchingPointcut在类或方式上找特定的注解,需要JDK5以上版本org.springframework.aop.aspectj.AspectJExpressionPointcut利用AspectJ织入器以AspectJ语法评价切入点亮相式org.springframework.aop.support.ComposablePointcut利用诸如union()和intersection()等操纵组合两个或多个切入点org.springframework.aop.support.ControlFlowPointcut是一种特别的切入点,它们婚配另一个方式的控制流中的全数方式,即任何作为另一个方式的结果而间接或间接挪用的方式org.springframework.aop.support.JdkRegexpMethodPointcut对方式名利用正则表达式界说切入点,要JDK4以上org.springframework.aop.support.NameMatchMethodPointcut望文生义,这是对方式称号列表举行简单的婚配org.springframework.aop.support.DynamicMethodMatcherPointcut这个类作为建立静态切入点的基类org.springframework.aop.support.StaticMethodMatcherPointcut作为建立亮相切入点的基类四、利用StaticMethodMatcherPointcut来建立静态切入点


  • 建立一个类,两个方式。我们的目标就是只在walk()方式中建立围绕看护,打印一句,"I am a cute cat."
  1. public class Cat {    public void sleep(){        System.out.println("sleep....");    }    public void walk(){        System.out.println("walking....");    }}
复制代码

  • 建立切入点
  1. public class MethodPointcutDemo extends StaticMethodMatcherPointcut {    @Override    public boolean matches(Method method, Class aClass) {        return method.getName().equals("walk");    }    @Override    public ClassFilter getClassFilter() {        return clz -> clz == Cat.class;        //        上边的lambda表达式即是下边的这个//        return new ClassFilter() {//            @Override//            public boolean matches(Class clz) {//                return clz == Cat.class;//            }//        };    }}
复制代码
上边的lambda表达式可检察https://www.cnblogs.com/Lyn4ever/p/11967959.html,后边出现时只写lambda表达式,且不再说明
在上边这个方式中,固然,我们可以不用实现getClassFilter()方式,由于这个方式已经被下级实现过了,我们便可以在matches方式中间接去判定这个类能否是Cat.class


  • 看护类(这个和上一次是一样的,建立一个围绕看护)
  1. import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class CatAdvisor implements MethodInterceptor{    @Override    public Object invoke(MethodInvocation invocation) throws Throwable {        //最不靠谱的方式,我们可以在这里判定这个method的能否是walk,从而要不要举行看护        System.out.println("I am a cute Cat.");        Object proceed = invocation.proceed();        return proceed;    }}
复制代码
固然,我们在这里也是可以判定这个方式名和类名的,为什么还要用切入点呢。可是这并不靠谱,我们中需要在这里实现我们的逻辑代码,而经过切入点来控制哪个类,哪个方式要被看护,这样更灵活。


  • 测试方式
  1. public static void main(String[] args) {        Cat cat = new Cat();        Pointcut pointcut = new MethodPointcutDemo();//切入点实例        Advice advice = new CatAdvisor();//看护类实例(就是我们的看护代码寄存的类的工具)        Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);//切面类,就是切入点和看护类的聚集        ProxyFactory proxyFactory = new ProxyFactory();        //和之前代码的区分就是这一句,这里我们利用的是切入点控制,假如把这句诠氏缢,就要用设备看护类        proxyFactory.addAdvisor(advisor);//设备切面类,包含切入点(控制看护点)和看护类(逻辑代码)                //假如诠氏缢上面一句,用这一句的话,就会对这个类中的全数方式都看护//        proxyFactory.addAdvice(advice);//设备看护类        proxyFactory.setTarget(cat);        Cat proxy = (Cat) proxyFactory.getProxy();        proxy.sleep();        proxy.walk();    }
复制代码
运转结果必定就是我们想的那样
  1. sleep....I am a cute Cat.walking....
复制代码
五、利用DyanmicMatcherPointcut建立静态切入点

这个和上边的静态切入点是一样的,只不外是让传入方式的参数满足必定要求时,才会尝试看护。由于篇幅原因原由,就不写了,在本文末端下载代码就能看懂。
六、其他典范的PointCut的实现类

1.简单的称号婚配 ( NameMatchMethodPointcut )

目标类和看护类还是之前的Cat类,之前的切入点的实现类不用写,由于这个类已经做了默许实现,感爱好的可以看下它的源码,很简单的,就是婚配类名,和我们适才建立的静态切入点差不多。
  1. public class NameMatchPointcutDemo {    public static void main(String[] args) {        Cat cat = new Cat();        //这个类已经是个实现类,我们就不需要再去写实现类了        NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();        pointcut.addMethodName("walk");        Advisor advisor = new DefaultPointcutAdvisor(pointcut,new CatAdvisor());        ProxyFactory proxyFactory = new ProxyFactory();        proxyFactory.addAdvisor(advisor);        proxyFactory.setTarget(cat);        Cat proxy = (Cat) proxyFactory.getProxy();        proxy.sleep();        proxy.walk();    }}
复制代码
2.利用正则表达式建立切入点 ( JdkRegexpMethodPointcut )

只写测试类,其他的都和上边一样
  1. public class JdkRegexpPointcutDemo {    public static void main(String[] args) {        Cat cat = new Cat();        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();        pointcut.setPattern(".*ee.*");//婚配中心有ee字母的,sleep()        Advisor advisor = new DefaultPointcutAdvisor(pointcut,new CatAdvisor());        ProxyFactory proxyFactory = new ProxyFactory();        proxyFactory.addAdvisor(advisor);        proxyFactory.setTarget(cat);        Cat proxy = (Cat) proxyFactory.getProxy();        proxy.sleep();        proxy.walk();    }}
复制代码
3.利用AspectJ切入点表达式建立切入点 ( AspectJExpressionPointcut )

利用AspectJ时要参加相关依靠
  1.           org.aspectj      aspectjrt      1.9.1              org.aspectj      aspectjweaver      1.9.1   
复制代码
  1. public class AspectJExpressionPointcutDemo {    public static void main(String[] args) {        Cat cat = new Cat();        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();        pointcut.setExpression("execution(* walk*(..))");        Advisor advisor = new DefaultPointcutAdvisor(pointcut, new CatAdvisor());        ProxyFactory proxyFactory = new ProxyFactory();        proxyFactory.addAdvisor(advisor);        proxyFactory.setTarget(cat);        Cat proxy = (Cat) proxyFactory.getProxy();        proxy.sleep();        proxy.walk();    }}
复制代码
这个execution表达式的意义是:任何以walk开首的,具有任何参数和任何返回值的方式
4.建立注解婚配的切入点 ( AnnotationMatchingPointcut )

首先自界说一个注解,假如不是很懂,参考Java中自界说注解类,并加以应用
  1. /** * 这个注解是用于运转期间、可用于类、方式上 */@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE,ElementType.METHOD})public @interface MyAdvice {}
复制代码
然后在目标方式上增加这个注解(要被看护的类)
  1.     /**     * 为了不与之前的辩说,就新写了一个方式     */    @MyAdvice    public void eat(){        System.out.println("eating....");    }
复制代码
然后在main方式中指定这个注解名:
  1. public class AnnotationPointcutDemo {    public static void main(String[] args) {        Cat cat = new Cat();        AnnotationMatchingPointcut pointcut = AnnotationMatchingPointcut                .forMethodAnnotation(MyAdvice.class);        //这个类另有一个.forClassAnnotation()方式,就是指定类的        Advisor advisor = new DefaultPointcutAdvisor(pointcut, new CatAdvisor());        ProxyFactory proxyFactory = new ProxyFactory();        proxyFactory.addAdvisor(advisor);        proxyFactory.setTarget(cat);        Cat proxy = (Cat) proxyFactory.getProxy();        proxy.sleep();//不会被看护        proxy.walk();//不会被看护        proxy.eat();//会被看护    }}
复制代码
代码已上传至github,假如爱好,就给个star
上一篇:SpringAOP根柢

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 妈妈网-中国妈妈第一,是怀孕、育儿、健康等知识交流传播首选平台 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表