欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Spring@Async的使用與實(shí)現(xiàn)的示例代碼

首先Spring AOP有兩個(gè)重要的基礎(chǔ)接口,Advisor和PointcutAdvisor,接口聲明如下:

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、永靖網(wǎng)絡(luò)推廣、小程序制作、永靖網(wǎng)絡(luò)營(yíng)銷、永靖企業(yè)策劃、永靖品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供永靖建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:aaarwkj.com

Advisor接口聲明:

public interface Advisor {
  Advice getAdvice();
  boolean isPerInstance();

}

PointcutAdvisor的接口聲明:

public interface PointcutAdvisor extends Advisor {

  /**
   * Get the Pointcut that drives this advisor.
   */
  Pointcut getPointcut();

}

PointcutAdvisor用來(lái)獲取一個(gè)切點(diǎn)以及這個(gè)切點(diǎn)的處理器(Advise)。

@Async注解使用后置處理器BeanPostProcessor的子類AsyncAnnotationBeanPostProcessor來(lái)實(shí)現(xiàn)bean處理 :

AsyncAnnotationAdvisor繼承了PointcutAdvisor接口。并且在AsyncAnnotationBeanPostProcessor實(shí)現(xiàn)了其父類接口的BeanFactoryAware中的setBeanFactory初始化。Spring一旦創(chuàng)建beanFactory回調(diào)成功,就會(huì)回調(diào)這個(gè)方法。保證Advisor對(duì)象最先被初始化。

  @Override
  public void setBeanFactory(BeanFactory beanFactory) {
    super.setBeanFactory(beanFactory);

    AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
    if (this.asyncAnnotationType != null) {
      advisor.setAsyncAnnotationType(this.asyncAnnotationType);
    }
    advisor.setBeanFactory(beanFactory);
    this.advisor = advisor;
  }

}

具體的后置處理是通過(guò)AsyncAnnotationBeanPostProcessor的后置bean處理是通過(guò)其父類AbstractAdvisingBeanPostProcessor來(lái)實(shí)現(xiàn)的。AbstractAdvisingBeanPostProcessor提供的后置bean處理方法對(duì)所有的自定義注解的bean處理方法時(shí)通用的。其具體的代碼如下:

@Override
  public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean instanceof AopInfrastructureBean) {
      // Ignore AOP infrastructure such as scoped proxies.
      return bean;
    }
   
   /*
   
   * bean對(duì)象如果是一個(gè)ProxyFactory對(duì)象。ProxyFactory繼承了AdvisedSupport,而    AdvisedSupport又繼承了Advised接口。這個(gè)時(shí)候就把不同的Advisor添加起來(lái)。
   *
    if (bean instanceof Advised) {
      Advised advised = (Advised) bean;
      if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
        // Add our local Advisor to the existing proxy's Advisor chain...
        if (this.beforeExistingAdvisors) {
          advised.addAdvisor(0, this.advisor);
        }
        else {
          advised.addAdvisor(this.advisor);
        }
        return bean;
      }
    }

    if (isEligible(bean, beanName)) {
      ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
      if (!proxyFactory.isProxyTargetClass()) {
        evaluateProxyInterfaces(bean.getClass(), proxyFactory);
      }
      proxyFactory.addAdvisor(this.advisor);
      customizeProxyFactory(proxyFactory);
      return proxyFactory.getProxy(getProxyClassLoader());
    }

可以看得出來(lái),isEligible用于判斷這個(gè)類或者這個(gè)類中的某個(gè)方法是否含有注解。這個(gè)方法最終進(jìn)入到AopUtils的canApply方法中間:

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    if (advisor instanceof IntroductionAdvisor) {
      return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    }
    else if (advisor instanceof PointcutAdvisor) {
      PointcutAdvisor pca = (PointcutAdvisor) advisor;
      return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    }
    else {
      // It doesn't have a pointcut so we assume it applies.
      return true;
    }
  }

這里的advisor就是AsyncAnnotationAdvisor對(duì)象。然后調(diào)用AsyncAnnotationAdvisor對(duì)象的getPointcut()方法,得到了Pointcut對(duì)象。在AOP規(guī)范中間,表示一個(gè)具體的切點(diǎn)。那么在方法上注釋@Async注解,就意味著聲明了一個(gè)切點(diǎn)。

然后再根據(jù)Pointcut判斷是否含有指定的注解。

切點(diǎn)的執(zhí)行

由于生成了JDK動(dòng)態(tài)代理對(duì)象,那么每一個(gè)方法的執(zhí)行必然進(jìn)入到JdkDynamicAopProxy中的invoke方法中間去執(zhí)行:

@Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    MethodInvocation invocation;
    Object oldProxy = null;
    boolean setProxyContext = false;

    TargetSource targetSource = this.advised.targetSource;
    Class<?> targetClass = null;
    Object target = null;

    try {
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
        // The target does not implement the equals(Object) method itself.
        return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
        // The target does not implement the hashCode() method itself.
        return hashCode();
      }
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
        // There is only getDecoratedClass() declared -> dispatch to proxy config.
        return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
          method.getDeclaringClass().isAssignableFrom(Advised.class)) {
        // Service invocations on ProxyConfig with the proxy config...
        return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
      }

      Object retVal;

      if (this.advised.exposeProxy) {
        // Make invocation available if necessary.
        oldProxy = AopContext.setCurrentProxy(proxy);
        setProxyContext = true;
      }

      // May be null. Get as late as possible to minimize the time we "own" the target,
      // in case it comes from a pool.
      target = targetSource.getTarget();
      if (target != null) {
        targetClass = target.getClass();
      }

      // Get the interception chain for this method.
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      // Check whether we have any advice. If we don't, we can fallback on direct
      // reflective invocation of the target, and avoid creating a MethodInvocation.
      if (chain.isEmpty()) {
        // We can skip creating a MethodInvocation: just invoke the target directly
        // Note that the final invoker must be an InvokerInterceptor so we know it does
        // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
        retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
        // We need to create a method invocation...
        invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
        // Proceed to the joinpoint through the interceptor chain.
        retVal = invocation.proceed();
      }

      // Massage return value if necessary.
      Class<?> returnType = method.getReturnType();
      if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
          !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
        // Special case: it returned "this" and the return type of the method
        // is type-compatible. Note that we can't help if the target sets
        // a reference to itself in another returned object.
        retVal = proxy;
      }
      else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
        throw new AopInvocationException(
            "Null return value from advice does not match primitive return type for: " + method);
      }
      return retVal;
    }
    finally {
      if (target != null && !targetSource.isStatic()) {
        // Must have come from TargetSource.
        targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
        // Restore old proxy.
        AopContext.setCurrentProxy(oldProxy);
      }
    }
  }

重點(diǎn)的執(zhí)行語(yǔ)句:

// 獲取攔截器
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      // Check whether we have any advice. If we don't, we can fallback on direct
      // reflective invocation of the target, and avoid creating a MethodInvocation.
      if (chain.isEmpty()) {
        // We can skip creating a MethodInvocation: just invoke the target directly
        // Note that the final invoker must be an InvokerInterceptor so we know it does
        // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
        retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
      
        // 根據(jù)攔截器來(lái)執(zhí)行
        invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
        // Proceed to the joinpoint through the interceptor chain.
        retVal = invocation.proceed();
      }

@Async注解的攔截器是AsyncExecutionInterceptor,它繼承了MethodInterceptor接口。而MethodInterceptor就是AOP規(guī)范中的Advice(切點(diǎn)的處理器)。

自定義注解

由于其bean處理器是通用的,所以只要實(shí)現(xiàn)PointcutAdvisor和具體的處理器就好了。首先自定義一個(gè)注解,只要方法加入了這個(gè)注解,就可以輸出這個(gè)方法的開(kāi)始時(shí)間和截止時(shí)間,注解的名字叫做@Log:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {

}

定義一個(gè)簡(jiǎn)單的方法用于測(cè)試:

public interface IDemoService {

  void add(int a, int b);
  String getName();
}
@Service
public class DemoServiceImpl implements IDemoService {

  
  @Log
  
  public void add(int a, int b) {
    System.out.println(Thread.currentThread().getName());
    System.out.println(a + b);

  }

  @Override
  public String getName() {
    System.out.println("DemoServiceImpl.getName");
    return "DemoServiceImpl";
  }

}

定義Advisor:

public class LogAnnotationAdvisor extends AbstractPointcutAdvisor {

  private Advice advice;

  private Pointcut pointcut;

  public LogAnnotationAdvisor() {

    this.advice = new LogAnnotationInterceptor();
  }


  @Override
  public Advice getAdvice() {

    return this.advice;
  }

  @Override
  public boolean isPerInstance() {

    return false;
  }

  @Override
  public Pointcut getPointcut() {

    return this.pointcut;
  }

  public void setAsyncAnnotationType(Class<? extends Annotation> asyncAnnotationType) {
    Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null");
    Set<Class<? extends Annotation>> asyncAnnotationTypes = new HashSet<Class<? extends Annotation>>();
    asyncAnnotationTypes.add(asyncAnnotationType);
    this.pointcut = buildPointcut(asyncAnnotationTypes);
  }

  protected Pointcut buildPointcut(Set<Class<? extends Annotation>> asyncAnnotationTypes) {
    ComposablePointcut result = null;
    for (Class<? extends Annotation> asyncAnnotationType : asyncAnnotationTypes) {
      Pointcut cpc = new AnnotationMatchingPointcut(asyncAnnotationType, true);
      Pointcut mpc = AnnotationMatchingPointcut.forMethodAnnotation(asyncAnnotationType);
      if (result == null) {
        result = new ComposablePointcut(cpc).union(mpc);
      } else {
        result.union(cpc).union(mpc);
      }
    }
    return result;
  }

}

定義具體的處理器:

public class LogAnnotationInterceptor implements MethodInterceptor, Ordered {

  @Override
  public int getOrder() {

    return Ordered.HIGHEST_PRECEDENCE;
  }

  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    System.out.println("開(kāi)始執(zhí)行");
    Object result = invocation.proceed();
    System.out.println("結(jié)束執(zhí)行");
    return result;
  }

}

定義@Log專屬的BeanPostProcesser對(duì)象:

@SuppressWarnings("serial")
@Service
public class LogAnnotationBeanPostProcesser extends AbstractBeanFactoryAwareAdvisingPostProcessor {

  @Override
  public void setBeanFactory(BeanFactory beanFactory) {
    super.setBeanFactory(beanFactory);
    LogAnnotationAdvisor advisor = new LogAnnotationAdvisor();
    advisor.setAsyncAnnotationType(Log.class);
    this.advisor = advisor;
  }



}

對(duì)bean的后置處理方法直接沿用其父類的方法。當(dāng)然也可以自定義其后置處理方法,那么就需要自己判斷這個(gè)對(duì)象的方法是否含有注解,并且生成代理對(duì)象:

@Override
  public Object postProcessAfterInitialization(Object bean, String beanName) {

    Method[] methods = ReflectionUtils.getAllDeclaredMethods(bean.getClass());
    for (Method method : methods) {
      if (method.isAnnotationPresent(Log.class)) {
        ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
        System.out.println(proxyFactory);
        if (!proxyFactory.isProxyTargetClass()) {
          evaluateProxyInterfaces(bean.getClass(), proxyFactory);
        }
        proxyFactory.addAdvisor(this.advisor);  
        customizeProxyFactory(proxyFactory);
        return proxyFactory.getProxy(getProxyClassLoader());
      }
    }
    return bean;

  }

測(cè)試注解是否是正常運(yùn)行的:

public class Main {
  public static void main(String[] args) {
    @SuppressWarnings("resource")
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml"); 
     IDemoService demoService = context.getBean(IDemoService.class);   
     demoService.add(1, 2);
     demoService.getName();
////     AsyncAnnotationAdvisor
//    AsyncAnnotationBeanPostProcessor
     
    
  }
}

輸出:

開(kāi)始執(zhí)行
main
3
結(jié)束執(zhí)行
DemoServiceImpl.getName

功能一切正常。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

網(wǎng)站欄目:Spring@Async的使用與實(shí)現(xiàn)的示例代碼
瀏覽路徑:http://aaarwkj.com/article6/jeipog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、企業(yè)建站、網(wǎng)站策劃、自適應(yīng)網(wǎng)站移動(dòng)網(wǎng)站建設(shè)、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
日韩经典三级精品自拍| 亚洲精品天堂av免费看| 人妻一少妇一区二区三区| 特黄特色的日本大片| 国产又粗又爽视频免费| 国产亚洲视频一区二区观看| 人妻一区二区三区免看| 人妻一少妇一区二区三区| 视频精品一区二区在线观看| 亚洲欧洲日本在线天堂| 高潮内射主播自拍一区| 国产精品一品二区三区在线观看| 成人免费亚洲av在线| 日韩精品一区二区视频在线| 亚洲欧美日韩一区二区视频| 日韩人妻熟妇中文字幕| 久久热视频这里有精品| 久久这里只有精品热免费| 欧美黄色影院在线观看| 久久婷婷欧美激情综合| 人妻操人人妻中出av| 蜜臀国产午夜在线视频| 男人天堂插插综合搜索| 中文字幕久久一区二区三区| 日本不卡的三区四区五区| 91在线人妻一区二区三区| 国产污视频网站在线观看| 中日韩一二三四区在线看| 最近中文字幕免费手机版| 国产第一页国产第一页| 日本成人午夜在线观看| 日本午夜理论视频在线播放| 大香蕉欧美日韩在线视频| 日韩欧美亚洲综合久久精品| 日本高清不卡在线观看| 亚洲日本精品国产第一区| 91无人区一区二区三乱码| 人妻天堂久久一区二区三区| 日韩三级精品一区二区| 精品亚洲一区二区三区四区 | 日韩综合欧美激情另类|