老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業(yè)提供網(wǎng)站建設(shè)、域名注冊(cè)、服務(wù)器等服務(wù)

Springboot中TargetSource的作用是什么

這篇文章將為大家詳細(xì)講解有關(guān)Springboot中TargetSource的作用是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

在柯橋等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需制作網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都全網(wǎng)營(yíng)銷推廣,成都外貿(mào)網(wǎng)站制作,柯橋網(wǎng)站建設(shè)費(fèi)用合理。

摘要:

其實(shí)proxy代理的不是target,而是TargetSource,這點(diǎn)非常重要,一定要分清楚!!!

通常情況下,一個(gè)代理對(duì)象只能代理一個(gè)target,每次方法調(diào)用的目標(biāo)也是唯一固定的target。但是,如果讓proxy代理TargetSource,可以使得每次方法調(diào)用的target實(shí)例都不同(當(dāng)然也可以相同,這取決于TargetSource實(shí)現(xiàn))。這種機(jī)制使得方法調(diào)用變得靈活,可以擴(kuò)展出很多高級(jí)功能,如:單利,原型,本地線程,目標(biāo)對(duì)象池、運(yùn)行時(shí)目標(biāo)對(duì)象熱替換目標(biāo)源等等。

Springboot中TargetSource的作用是什么

Spring內(nèi)置的TargetSource
SingletonTargetSource
    public class SingletonTargetSource implements TargetSource, Serializable {
    
    	/** Target cached and invoked using reflection. */
    	private final Object target;
    	//省略無(wú)關(guān)代碼......
    	@Override
    	public Object getTarget() {
    		return this.target;
    	}
    	//省略無(wú)關(guān)代碼......
    }

從這個(gè)目標(biāo)源取得的目標(biāo)對(duì)象是單例的,成員變量target緩存了目標(biāo)對(duì)象,每次getTarget()都是返回這個(gè)對(duì)象。

PrototypeTargetSource
    public class PrototypeTargetSource extends AbstractPrototypeBasedTargetSource {
    
       /**
        * Obtain a new prototype instance for every call.
        * @see #newPrototypeInstance()
        */
       @Override
       public Object getTarget() throws BeansException {
          return newPrototypeInstance();
       }
    
       /**
        * Destroy the given independent instance.
        * @see #destroyPrototypeInstance
        */
       @Override
       public void releaseTarget(Object target) {
          destroyPrototypeInstance(target);
       }
      //省略無(wú)關(guān)代碼......
    }

每次getTarget()將生成prototype類型的bean,即其生成的bean并不是單例的,因而使用這個(gè)類型的TargetSource時(shí)需要注意,封裝的目標(biāo)bean必須是prototype類型的。PrototypeTargetSource繼承了AbstractBeanFactoryBasedTargetSource擁有了創(chuàng)建bean的能力。

    public abstract class AbstractPrototypeBasedTargetSource extends AbstractBeanFactoryBasedTargetSource {
    
       //省略無(wú)關(guān)代碼......
       /**
        * Subclasses should call this method to create a new prototype instance.
        * @throws BeansException if bean creation failed
        */
       protected Object newPrototypeInstance() throws BeansException {
          if (logger.isDebugEnabled()) {
             logger.debug("Creating new instance of bean '" + getTargetBeanName() + "'");
          }
          return getBeanFactory().getBean(getTargetBeanName());
       }
    
       /**
        * Subclasses should call this method to destroy an obsolete prototype instance.
        * @param target the bean instance to destroy
        */
       protected void destroyPrototypeInstance(Object target) {
          if (logger.isDebugEnabled()) {
             logger.debug("Destroying instance of bean '" + getTargetBeanName() + "'");
          }
          if (getBeanFactory() instanceof ConfigurableBeanFactory) {
             ((ConfigurableBeanFactory) getBeanFactory()).destroyBean(getTargetBeanName(), target);
          }
          else if (target instanceof DisposableBean) {
             try {
                ((DisposableBean) target).destroy();
             }
             catch (Throwable ex) {
                logger.warn("Destroy method on bean with name '" + getTargetBeanName() + "' threw an exception", ex);
             }
          }
       }
    
      //省略無(wú)關(guān)代碼......
    
    }

可以看到,PrototypeTargetSource的生成prototype類型bean的方式主要是委托給BeanFactory進(jìn)行的,因?yàn)锽eanFactory自有一套生成prototype類型的bean的邏輯,因而PrototypeTargetSource也就具有生成prototype類型bean的能力,這也就是我們要生成的目標(biāo)bean必須聲明為prototype類型的原因。

ThreadLocalTargetSource
    public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
          implements ThreadLocalTargetSourceStats, DisposableBean {
    
       /**
        * ThreadLocal holding the target associated with the current
        * thread. Unlike most ThreadLocals, which are static, this variable
        * is meant to be per thread per instance of the ThreadLocalTargetSource class.
        */
       private final ThreadLocal targetInThread =
             new NamedThreadLocal<>("Thread-local instance of bean '" + getTargetBeanName() + "'");
    
       /**
        * Set of managed targets, enabling us to keep track of the targets we've created.
        */
       private final Set targetSet = new HashSet<>();
    
     //省略無(wú)關(guān)代碼......
       /**
        * Implementation of abstract getTarget() method.
        * We look for a target held in a ThreadLocal. If we don't find one,
        * we create one and bind it to the thread. No synchronization is required.
        */
       @Override
       public Object getTarget() throws BeansException {
          ++this.invocationCount;
          Object target = this.targetInThread.get();
          if (target == null) {
             if (logger.isDebugEnabled()) {
                logger.debug("No target for prototype '" + getTargetBeanName() + "' bound to thread: " +
                      "creating one and binding it to thread '" + Thread.currentThread().getName() + "'");
             }
             // Associate target with ThreadLocal.
             target = newPrototypeInstance();
             this.targetInThread.set(target);
             synchronized (this.targetSet) {
                this.targetSet.add(target);
             }
          }
          else {
             ++this.hitCount;
          }
          return target;
       }
    
       /**
        * Dispose of targets if necessary; clear ThreadLocal.
        * @see #destroyPrototypeInstance
        */
       @Override
       public void destroy() {
          logger.debug("Destroying ThreadLocalTargetSource bindings");
          synchronized (this.targetSet) {
             for (Object target : this.targetSet) {
                destroyPrototypeInstance(target);
             }
             this.targetSet.clear();
          }
          // Clear ThreadLocal, just in case.
          this.targetInThread.remove();
       }
    //省略無(wú)關(guān)代碼......
    }

ThreadLocalTargetSource也就是和線程綁定的TargetSource,可以理解,其底層實(shí)現(xiàn)必然使用的是ThreadLocal。既然使用了ThreadLocal,也就是說(shuō)我們需要注意兩個(gè)問(wèn)題:

  • 目標(biāo)對(duì)象必須聲明為prototype類型,因?yàn)槊總€(gè)線程都會(huì)持有一個(gè)不一樣的對(duì)象;

  • 目標(biāo)對(duì)象必須是無(wú)狀態(tài)的,因?yàn)槟繕?biāo)對(duì)象是和當(dāng)前線程綁定的,而Spring是使用的線程池處理的請(qǐng)求,因而每個(gè)線程可能處理不同的請(qǐng)求,因而為了避免造成問(wèn)題,目標(biāo)對(duì)象必須是無(wú)狀態(tài)的。

實(shí)現(xiàn)自定義的TargetSource
    package com.github.dqqzj.springboot.target;
    
    import org.springframework.aop.TargetSource;
    import org.springframework.util.Assert;
    
    import java.lang.reflect.Array;
    import java.util.concurrent.ThreadLocalRandom;
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * @author qinzhongjian
     * @date created in 2019-08-25 12:43
     * @description: TODO
     * @since JDK 1.8.0_212-b10z
     */
    public class DqqzjTargetSource implements TargetSource {
        private final AtomicInteger idx = new AtomicInteger();
        private final Object[] target;;
        public DqqzjTargetSource(Object[]  target) {
            Assert.notNull(target, "Target object must not be null");
            this.target = target;
        }
        @Override
        public Class getTargetClass() {
            return target.getClass();
        }
    
        @Override
        public boolean isStatic() {
            return false;
        }
    
        @Override
        public Object getTarget() throws Exception {
            return this.target[this.idx.getAndIncrement() & this.target.length - 1];
        }
    
        @Override
        public void releaseTarget(Object target) throws Exception {
    
        }
    }

實(shí)現(xiàn)自定義TargetSource主要有兩個(gè)點(diǎn)要注意,一個(gè)是getTarget()方法,該方法中需要實(shí)現(xiàn)獲取目標(biāo)對(duì)象的邏輯,另一個(gè)是isStatic()方法,這個(gè)方法告知Spring是否需要緩存目標(biāo)對(duì)象,在非單例的情況下一般是返回false

關(guān)于Springboot中TargetSource的作用是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。


網(wǎng)頁(yè)名稱:Springboot中TargetSource的作用是什么
文章地址:http://www.xueling.net.cn/article/ghsdgd.html 主站蜘蛛池模板: yourporn久久久亚洲精品 | 国产桃色无码视频在线观看 | 欧美成人精品 | 激情文学小说区另类小说 | 日本午夜在线观看 | 国产视频网站在线 | 色婷婷香蕉在线一区二区 | 91精品国产91久久久久久三级 | 色视频亚洲 | 欧美人与拘牲交大全视频 | 国产精品国 | 好看av在线| 国产欧美在线视频 | 暖暖在线日本免费中文 | 在线免费黄色毛片 | 又硬又粗进去好爽免费 | 奇米影视777me | 日本japanesexxxx高潮 | 久久不见久久见www免费视频 | 欧美国产日韩在线 | 天天爽天天爽天天爽 | 中文字幕天使萌在线va | 久久国产午夜精品理论片 | 粉嫩av淫片一区二区三区 | 成人午夜免费在线视频 | 性生活一区 | 粉嫩饱饱鱼一线天在线观看 | 精品无码久久久久国产手机版 | 中文字幕在线国产 | 久久99精品国产麻豆婷婷小说 | 精品国产不卡一区二区三区 | 国产91精品久久久久久久网曝门 | 精品国产一区二区三区久久久 | 国产成人AV片无码免费 | 又黄又高潮的视频 | 国产1级| 国产精品麻豆99久久久久久 | 黄页在线观看视频 | 人与禽交videos欧美 | 中文字字幕乱码视频 | 午夜影院免费视频 |