91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Spring方法攔截器MethodInterceptor

發布時間:2021-10-27 09:11:05 來源:億速云 閱讀:722 作者:iii 欄目:開發技術

本篇內容主要講解“如何使用Spring方法攔截器MethodInterceptor”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何使用Spring方法攔截器MethodInterceptor”吧!

Spring方法攔截器MethodInterceptor

前言

實現MethodInterceptor 接口,在調用目標對象的方法時,就可以實現在調用方法之前、調用方法過程中、調用方法之后對其進行控制。

MethodInterceptor 接口可以實現MethodBeforeAdvice接口、AfterReturningAdvice接口、ThrowsAdvice接口這三個接口能夠所能夠實現的功能,但是應該謹慎使用MethodInterceptor 接口,很可能因為一時的疏忽忘記最重要的MethodInvocation而造成對目標對象方法調用失效,或者不能達到預期的設想。

示例代碼如下

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("通過代理工廠設置代理對象,攔截代理方法");
    }
    public static class adviseMethodInterceptor implements MethodInterceptor{
        @Override
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
            Object result=null;
            try{
                System.out.println("方法執行之前:"+methodInvocation.getMethod().toString());
                result= methodInvocation.proceed();
                System.out.println("方法執行之后:"+methodInvocation.getMethod().toString());
                System.out.println("方法正常運行結果:"+result);
                return result;
            }catch (Exception e){
                System.out.println("方法出現異常:"+e.toString());
                System.out.println("方法運行Exception結果:"+result);
                return result;
            }
        }
    }
    public String doSomeThing(String someThing){
        //int i=5/0;
        return "執行被攔截的方法:"+someThing;
    }
}

正常運行結果:

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

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

方法正常運行結果:執行被攔截的方法:通過代理工廠設置代理對象,攔截代理方法

異常運行結果:

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

方法出現異常:java.lang.ArithmeticException: / by zero

方法運行Exception結果:null

Spring攔截器實現+后臺原理(MethodInterceptor)

MethodInterceptor

MethodInterceptor是AOP項目中的攔截器(注:不是動態代理攔截器),區別與HandlerInterceptor攔截目標時請求,它攔截的目標是方法。

實現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>
        <!--切入點,controlller -->
        <aop:pointcut id="pointcut_test"   expression="execution(* com.paic.phssp.springtest.controller..*.*(..))" />
        <!--在該切入點使用自定義攔截器 ,按照先后順序執行 -->
        <aop:advisor pointcut-ref="pointcut_test" advice-ref="methodInvokeInterceptor" />
    </aop:config>
    <!-- 自動掃描使用了aspectj注解的類 -->
    <aop:aspectj-autoproxy/>

執行:

如何使用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;
    }
}

運行結果:

AutoAspectJInterceptor begin around......

>>>>:isAuthenticated=false

AutoAspectJInterceptor end around......

簡單介紹下關鍵詞
  • AOP=Aspect Oriented Program面向切面(方面/剖面)編程

  • Advice(通知):把各組件中公共業務邏輯抽離出來作為一個獨立 的組件

  • Weave(織入):把抽離出來的組件(Advice),使用到需要使用該邏輯 地方的過程。

  • JoinPoint (連接點): Advice 組件可以weave的特征點。

  • PointCut(切入點):用來明確Advice需要織入的連接點

  • Aspect(切面):Aspect=Advice + PointCut

通知類型

  • @Before 在切點方法之前執行

  • @After 在切點方法之后執行

  • @AfterReturning 切點方法返回后執行

  • @AfterThrowing 切點方法拋異常執行

  • @Around環繞通知

執行順序:

  • @Around環繞通知

  • @Before通知執行

  • @Before通知執行結束

  • @Around環繞通知執行結束

  • @After后置通知執行了!

  • @AfterReturning

切面設置

可以使用&&、||、!、三種運算符來組合切點表達式

execution表達式
"execution(public * com.xhx.springboot.controller.*.*(..))"
  • *只能匹配一級路徑

  • ..可以匹配多級,可以是包路徑,也可以匹配多個參數

  • + 只能放在類后面,表明本類及所有子類

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

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、注冊

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

如何使用Spring方法攔截器MethodInterceptor

看到實現接口BeanPostProcessor,必然在初始化Bean前后,執行接口方法。

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、具體實現

上面提到實現接口BeanPostProcessor,必然在初始化Bean前后,執行接口方法。看下面時序圖:

AbstractAutoProxyCreator的postProcessAfterInitialization()方法

如何使用Spring方法攔截器MethodInterceptor

DefaultAopProxyFactory.createAopProxy()方法,具體創建代理類。兩種動態代理:JDK動態代理和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));
            }
        }
    }

到此,相信大家對“如何使用Spring方法攔截器MethodInterceptor”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

四子王旗| 昆明市| 河曲县| 炉霍县| 桃源县| 惠安县| 鄢陵县| 双鸭山市| 平邑县| 河北省| 连平县| 浦东新区| 稻城县| 湾仔区| 奉化市| 沙坪坝区| 密云县| 江门市| 边坝县| 酒泉市| 马鞍山市| 梅州市| 雅江县| 乃东县| 瓮安县| 渝北区| 滁州市| 依兰县| 和平区| 息烽县| 舞钢市| 兴安盟| 剑阁县| 黑河市| 华蓥市| 乾安县| 泸西县| 公安县| 溧水县| 竹溪县| 西贡区|