博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring学习笔记(六)
阅读量:6164 次
发布时间:2019-06-21

本文共 4784 字,大约阅读时间需要 15 分钟。

hot3.png

回顾

        前文提到了一个切面(Aspect)由切点(Pointcut)和增强(Advice)组成,切点提供了连接点的具体类的具体方法信息,而增强提供了横切代码以及其织入方法的位子,当单独使用增强时,会默认的作用于类的所有方法上,想要指定特定的方法就需要切点的使用了,下面进行切点的讲解,增强请看上一篇笔记。

切点(Pointcut)

        Spring通过org.springframwork.aop.Pointcut接口描述切点,Pointcut由ClassFilter和MethodMatcher构成,通过ClassFilter对位具体的类,通过Methodmatcher定位方法。Spring支持两种方法匹配器:静态方法匹配器和动态方法匹配器,方法匹配器的类型以isRuntime()返回值决定,false为静态。

        Spring提供了6种类型的切点:静态方法切点、动态方法切点、注解切点、表达式切点、流程切点、复合切点

静态方法切点

        org.springframework.aop.support.StaticMethodMatcherPoint,默认匹配所有类包含两个主要的子类NameMethodmatcherPoint和AbstractRegexpMatcherPoint从类名就可以看出,前者是通过简单字符串匹配方法签名,后者是通过正则表达式配置方法签名。

静态普通方法名匹配切面

还是以之前睡觉前要洗漱为例:

package advisor;public class Person {    public void sleep() {        System.out.println("I am sleeping.....ZZZZ");    }    public void work() {        System.out.println("I am working....");    }}

我们只希望在sleep方法的前面加上洗漱而不影响work,使用前置增强:

package advice;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class GreetingBeforeAdvice implements MethodBeforeAdvice {    @Override    public void before(Method method, Object[] args, Object target) throws Throwable {        System.out.println("I am washing face.....");    }}

使用静态方法切点:

public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor {    @Override    public boolean matches(Method method, Class
 targetClass) {        return "sleep".equals(method.getName());    }    @Override    public ClassFilter getClassFilter() {        return new ClassFilter() {            @Override            public boolean matches(Class
 clazz) {                return Person.class.isAssignableFrom(clazz);            }        };    }}

可以看到通过重写matchs方法,和getClassFilter方法我们只匹配Person类的sleep方法,使用TestNG测试:

package advisor;import advice.GreetingBeforeAdvice;import org.springframework.aop.framework.ProxyFactory;import org.testng.annotations.BeforeTest;import org.testng.annotations.Test;public class GreetingAdvisorTest {    private ProxyFactory pf;    private Person person;    private GreetingAdvisor advisor;    private GreetingBeforeAdvice advice;    @BeforeTest    public void init() {        person = new Person();        advisor = new GreetingAdvisor();        advice = new GreetingBeforeAdvice();        pf = new ProxyFactory();        advisor.setAdvice(advice);        pf.setTarget(person);        pf.addAdvisor(advisor);    }    @Test    public void testStaticMethodAdvisor() {        person = (Person)pf.getProxy();        person.sleep();        System.out.println("-------------------------------");        person.work();    }}

结果:

I am washing face.....I am sleeping.....ZZZZ-------------------------------I am working....

达到了预期目标。

Spring配置文件的配置方式:

......

初始化ApplicationContext获取person的实例,即可使用,效果同上

静态正则表达式方法匹配切面

        这种方式使用正则表达式去匹配方法的签名,正则表达式的内容比较多,这里就不介绍了,使用方式与上面大同小异,只是在匹配方法时不时直接比较字符串,而是用正则表达式匹配,例子相同部分就不再提。RegexpMethodPointcutAdvisor是正则表达式的切面实现类,该类功能已经齐备,一般情况下,不需要再继承重写他的方法或扩占方法。

spring配置文件中配置如下:

......
        
            
                
.*sleep.*
            
        

直接使用ProxyFactory代码:

package advisor;import advice.GreetingBeforeAdvice;import org.springframework.aop.framework.ProxyFactory;import org.springframework.aop.support.RegexpMethodPointcutAdvisor;import org.testng.annotations.BeforeTest;import org.testng.annotations.Test;/** * Created by rex.chen on 14-1-24. */public class GreetingAdvisorTest {    private ProxyFactory pf;    private Person person;    private GreetingBeforeAdvice advice;    private RegexpMethodPointcutAdvisor regexp;    @BeforeTest    public void init() {        person = new Person();        advice = new GreetingBeforeAdvice();        regexp = new RegexpMethodPointcutAdvisor();        pf = new ProxyFactory();        regexp.setAdvice(advice);        regexp.setPattern(".*sleep.*");        pf.setTarget(person);        pf.addAdvisor(regexp);    }    @Test    public void testStaticMethodAdvisor() {        person = (Person)pf.getProxy();        person.sleep();        System.out.println("-------------------------------");        person.work();    }}

动态方法切点

        org.springframework.aop.support.DynamicMethodMatcherPointcut是动态方法切点的抽象基类,默认情况下匹配所有的类。动态方法切点与静态方法切点的区别是前者使用动态方法匹配器,后者使用静态方法匹配器,区别在于动态方法匹配器会在运行期检查方法的入参的值来匹配方法,每次调用方法时都将检查一次入参,所以对性能影响很大,而静态配置只会匹配一次,所以一般不会用动态方法切点,这里就不介绍了

注解切点

        org.springframework.aop.support.annotation.AnnotationMatcherPointcut实现类表示注解切点,可以使用注解配置切点,后面再详细介绍

表达式切点

        org.springframwork.aop.support.ExpressionPointcut接口主要是为了支持AspectJ切点表达式语言而定义的接口,后面再详细介绍

流程切点

        org.springframwork.aop.support.ControlFlowPointcut,根据程序执行的堆栈信息查看目标方法是否由某一个方法直接或间接发起调用,以此判断是否为匹配的连接点,这里不详细介绍。

复合切点

        org.springframwork.aop.support.ComposablePointcut可以使用链式编程创建多个切点,这里不详细介绍。

转载于:https://my.oschina.net/u/1413049/blog/195471

你可能感兴趣的文章
极客技术专题【009期】:web技术开发小技巧
查看>>
PHP 简单计算器代码实现
查看>>
正则表达式的知识普及
查看>>
docker使用笔记
查看>>
华为eNSP模拟器上实现FTP服务
查看>>
【全球AI人才排行榜】美国第一,中国仅排名第7
查看>>
微信小程序输入框input
查看>>
MySql字符串函数使用技巧
查看>>
Doc2Vec,Word2Vec文本相似度 初体验。
查看>>
系统ghost后变成一个盘了别的分区的文件怎么找回
查看>>
Win7+Ubuntu11
查看>>
请问华为三层交换机里面的那个从IP是个什么意思? -
查看>>
kFeedback开源啦
查看>>
大数据传输,文件传输的专业解决方案!
查看>>
阿里云专家穆轩的《杭州九年程序员之“修炼”手册》
查看>>
JQuery:deferred对象的方法
查看>>
eyoucms问答 百度权重是什么
查看>>
win10中遇到qq视频时摄像头打不开没反应的解决方法
查看>>
介绍自己的一个Android插桩热修复框架项目QuickPatch
查看>>
关于textarea的ie9的maxlength不起作用的问题,请参考如下URL解决。
查看>>