一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 使用Spring方法攔截器MethodInterceptor

使用Spring方法攔截器MethodInterceptor

2022-03-02 00:33淡淡的倔強(qiáng) Java教程

這篇文章主要介紹了使用Spring方法攔截器MethodInterceptor,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

 

Spring方法攔截器MethodInterceptor

 

前言

實(shí)現(xiàn)MethodInterceptor 接口,在調(diào)用目標(biāo)對(duì)象的方法時(shí),就可以實(shí)現(xiàn)在調(diào)用方法之前、調(diào)用方法過程中、調(diào)用方法之后對(duì)其進(jìn)行控制。

MethodInterceptor 接口可以實(shí)現(xiàn)MethodBeforeAdvice接口、AfterReturningAdvice接口、ThrowsAdvice接口這三個(gè)接口能夠所能夠?qū)崿F(xiàn)的功能,但是應(yīng)該謹(jǐn)慎使用MethodInterceptor 接口,很可能因?yàn)橐粫r(shí)的疏忽忘記最重要的MethodInvocation而造成對(duì)目標(biāo)對(duì)象方法調(diào)用失效,或者不能達(dá)到預(yù)期的設(shè)想。

示例代碼如下

public class TestMethodInterceptor  {
    public static void main(String[] args) {
        ProxyFactory proxyFactory=new ProxyFactory();
        proxyFactory.setTarget(new TestMethodInterceptor());
        proxyFactory.addAdvice(new adviseMethodInterceptor());
        Object proxy = proxyFactory.getProxy();
        TestMethodInterceptor methodInterceptor = (TestMethodInterceptor) proxy;
        methodInterceptor.doSomeThing("通過代理工廠設(shè)置代理對(duì)象,攔截代理方法");
    }
    public static class adviseMethodInterceptor implements MethodInterceptor{
        @Override
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
            Object result=null;
            try{
                System.out.println("方法執(zhí)行之前:"+methodInvocation.getMethod().toString());
                result= methodInvocation.proceed();
                System.out.println("方法執(zhí)行之后:"+methodInvocation.getMethod().toString());
                System.out.println("方法正常運(yùn)行結(jié)果:"+result);
                return result;
            }catch (Exception e){
                System.out.println("方法出現(xiàn)異常:"+e.toString());
                System.out.println("方法運(yùn)行Exception結(jié)果:"+result);
                return result;
            }
        }
    }
    public String doSomeThing(String someThing){
        //int i=5/0;
        return "執(zhí)行被攔截的方法:"+someThing;
    }
}

正常運(yùn)行結(jié)果:

方法執(zhí)行之前:public java.lang.String com.blog.test.aop.TestMethodInterceptor.doSomeThing(java.lang.String)

方法執(zhí)行之后:public java.lang.String com.blog.test.aop.TestMethodInterceptor.doSomeThing(java.lang.String)

方法正常運(yùn)行結(jié)果:執(zhí)行被攔截的方法:通過代理工廠設(shè)置代理對(duì)象,攔截代理方法

異常運(yùn)行結(jié)果:

方法執(zhí)行之前:public java.lang.String com.blog.test.aop.TestMethodInterceptor.doSomeThing(java.lang.String)

方法出現(xiàn)異常:java.lang.ArithmeticException: / by zero

方法運(yùn)行Exception結(jié)果:null

 

Spring攔截器實(shí)現(xiàn)+后臺(tái)原理(MethodInterceptor)

 

MethodInterceptor

MethodInterceptor是AOP項(xiàng)目中的攔截器(注:不是動(dòng)態(tài)代理攔截器),區(qū)別與HandlerInterceptor攔截目標(biāo)時(shí)請(qǐng)求,它攔截的目標(biāo)是方法。

實(shí)現(xiàn)MethodInterceptor攔截器大致也分為兩種:

(1)MethodInterceptor接口;

(2)利用AspectJ的注解配置;

 

MethodInterceptor接口

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MethodInvokeInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("before method invoke....");
        Object object = methodInvocation.proceed();
        System.out.println("after method invoke.....");
        return object;
    }
}
<!-- 攔截器 demo -->
    <bean id="methodInvokeInterceptor" class="com.paic.phssp.springtest.interceptor.method.MethodInvokeInterceptor"/>
    <aop:config>
        <!--切入點(diǎn),controlller -->
        <aop:pointcut id="pointcut_test"   expression="execution(* com.paic.phssp.springtest.controller..*.*(..))" />
        <!--在該切入點(diǎn)使用自定義攔截器 ,按照先后順序執(zhí)行 -->
        <aop:advisor pointcut-ref="pointcut_test" advice-ref="methodInvokeInterceptor" />
    </aop:config>
    <!-- 自動(dòng)掃描使用了aspectj注解的類 -->
    <aop:aspectj-autoproxy/>

執(zhí)行:

使用Spring方法攔截器MethodInterceptor

 

AspectJ的注解

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AutoAspectJInterceptor {
    @Around("execution (* com.paic.phssp.springtest.controller..*.*(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable{
        System.out.println("AutoAspectJInterceptor begin around......");
        Object object = point.proceed();
        System.out.println("AutoAspectJInterceptor end around......");
        return object;
    }
}

運(yùn)行結(jié)果:

AutoAspectJInterceptor begin around......

>>>>:isAuthenticated=false

AutoAspectJInterceptor end around......

 

簡(jiǎn)單介紹下關(guān)鍵詞

  • AOP=Aspect Oriented Program面向切面(方面/剖面)編程
  • Advice(通知):把各組件中公共業(yè)務(wù)邏輯抽離出來作為一個(gè)獨(dú)立 的組件
  • Weave(織入):把抽離出來的組件(Advice),使用到需要使用該邏輯 地方的過程。
  • JoinPoint (連接點(diǎn)): Advice 組件可以weave的特征點(diǎn)。
  • PointCut(切入點(diǎn)):用來明確Advice需要織入的連接點(diǎn)
  • Aspect(切面):Aspect=Advice + PointCut

通知類型

  • @Before 在切點(diǎn)方法之前執(zhí)行
  • @After 在切點(diǎn)方法之后執(zhí)行
  • @AfterReturning 切點(diǎn)方法返回后執(zhí)行
  • @AfterThrowing 切點(diǎn)方法拋異常執(zhí)行
  • @Around環(huán)繞通知

執(zhí)行順序:

  • @Around環(huán)繞通知
  • @Before通知執(zhí)行
  • @Before通知執(zhí)行結(jié)束
  • @Around環(huán)繞通知執(zhí)行結(jié)束
  • @After后置通知執(zhí)行了!
  • @AfterReturning

 

切面設(shè)置

可以使用&&、||、!、三種運(yùn)算符來組合切點(diǎn)表達(dá)式

 

execution表達(dá)式

"execution(public * com.xhx.springboot.controller.*.*(..))"
  • *只能匹配一級(jí)路徑
  • ..可以匹配多級(jí),可以是包路徑,也可以匹配多個(gè)參數(shù)
  • + 只能放在類后面,表明本類及所有子類

within(類路徑) 配置指定類型的類實(shí)例,同樣可以使用匹配符

within(com.xhx.springboot..*)

@within(annotationType) 匹配帶有指定注解的類(注:與上不同)

"@within(org.springframework.stereotype.Component)"

@annotation(annotationType) 匹配帶有指定注解的方法

"@annotation(IDataSource)"

其中:IDataSource為自定義注解

import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface IDataSource {
    String value() default "dataSource";
}

 

下面分析下Spring @Aspect

1、注冊(cè)

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

使用Spring方法攔截器MethodInterceptor

看到實(shí)現(xiàn)接口BeanPostProcessor,必然在初始化Bean前后,執(zhí)行接口方法。

2、解析

AspectJAutoProxyBeanDefinitionParser.java#parse()方法

@Nullable
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        this.extendBeanDefinition(element, parserContext);
        return null;
    }
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        registerComponentIfNecessary(beanDefinition, parserContext);
    }
@Nullable
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }

3、具體實(shí)現(xiàn)

上面提到實(shí)現(xiàn)接口BeanPostProcessor,必然在初始化Bean前后,執(zhí)行接口方法。看下面時(shí)序圖:

AbstractAutoProxyCreator的postProcessAfterInitialization()方法

使用Spring方法攔截器MethodInterceptor

DefaultAopProxyFactory.createAopProxy()方法,具體創(chuàng)建代理類。兩種動(dòng)態(tài)代理:JDK動(dòng)態(tài)代理和CGLIB代理。

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
            } else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/u012834750/article/details/71773887

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人夜色91 | 亚洲精品久久啪啪网站成年 | 男生的j桶女人屁免费视频 男生操男生 | japanesexxxx在线播放 | 亚洲精品老司机福利在线播放 | 99草精品视频 | 日韩欧美一区二区三区视频 | 国内亚州视频在线观看 | ass巨大胖女人sias | 欧美高清milf在线播放 | 日本人成在线视频免费播放 | 好吊操这里有精品 | 手机在线伦理片 | 国产女乱淫真高清免费视频 | 美女秘密网站 | 东北疯狂xxxxbbbb中国 | 三级黄色片在线观看 | 齐天大性之七仙女欲春迅雷链接 | 青青草精品在线观看 | 欧美xxxxxbb | 成人国产在线视频在线观看 | 午夜久久久久久网站 | 国产美女亚洲精品久久久综合91 | 精品国产午夜久久久久九九 | 久久综合老色鬼网站 | 超级毛片 | 国产精品欧美一区二区 | 久久精品亚洲牛牛影视 | 极端 成熟 性别 视频 | 韩国三级在线 | 精品区2区3区4区产品乱码9 | 国产日韩欧美在线一区二区三区 | 丰腴尤物贵妇浪荡小说 | 冰雪奇缘1完整版免费观看 变形金刚第一部 | 久久人妻熟女中文字幕AV蜜芽 | 国产欧美视频高清va在线观看 | 久久九九有精品国产23百花影院 | 欧美激烈精交gif动态图18p | 国产a一级毛片午夜剧院 | 四虎成人网 | 亚洲a区视频 |