日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

1 Scope作用

通過@Scope注解可以指定Bean的作用域,默認(rèn)情況都是單例的(
ConfigurableBeanFactory.SCOPE_SINGLETON=singleton)

在創(chuàng)建bean實例時就是根據(jù)當(dāng)前定義BeanDefinition中的Scope來做不同的創(chuàng)建,源碼如下:

protected <T> T doGetBean(            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)            throws BeansException {  String beanName = transformedBeanName(name);  Object bean;  // Eagerly check singleton cache for manually registered singletons.  Object sharedInstance = getSingleton(beanName);  if (sharedInstance != null && args == null) {    // other code  } else {    // other code    try {      RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);      checkMergedBeanDefinition(mbd, beanName, args);
      // Guarantee initialization of beans that the current bean depends on.      // other code      // Create bean instance.      // 根據(jù)BeanDefinition中定義的Scope創(chuàng)建實例      // 判斷如果是單例      if (mbd.isSingleton()) {        // 如果是單例Bean會將Bean保存到緩存中singletonObjects          sharedInstance = getSingleton(beanName, () -> {          try {            return createBean(beanName, mbd, args);          } catch (BeansException ex) {            destroySingleton(beanName);            throw ex;          }        });        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);      }      // 判斷如果是原型(多例)      else if (mbd.isPrototype()) {        // It's a prototype -> create a new instance.        Object prototypeInstance = null;        try {          beforePrototypeCreation(beanName);          prototypeInstance = createBean(beanName, mbd, args);        } finally {          afterPrototypeCreation(beanName);        }        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);      }       else {        String scopeName = mbd.getScope();        if (!StringUtils.hasLength(scopeName)) {          throw new IllegalStateException("No scope name defined for bean 麓" + beanName + "'");        }        Scope scope = this.scopes.get(scopeName);        // 當(dāng)集合中也不存在時拋出異常          if (scope == null) {          throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");        }        try {          Object scopedInstance = scope.get(beanName, () -> {            beforePrototypeCreation(beanName);            try {              return createBean(beanName, mbd, args);            } finally {              afterPrototypeCreation(beanName);            }          });          bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);        } catch (IllegalStateException ex) {          throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex);        }      }    } catch (BeansException ex) {      cleanupAfterBeanCreationFAIlure(beanName);      throw ex;    }  }  // other code  return (T) bean;}

從上面源碼看到分別判斷是了 是否是 Singleton及Proptotype,如果都不是則會從Map<String, Scope> scopes中獲取。如果當(dāng)前你配置的@Scope不是singleton及prototype那么從scopes集合中取(這個集合是通過AbstractBeanFactory#registerScope方法進(jìn)行注冊的,一般我們可以通過
BeanDefinitionRegistryPostProcessor進(jìn)行注冊),如果集合中也不存在那么就會拋出異常。如果存在就會執(zhí)行Scope#get方法

Scope scope = this.scopes.get(scopeName);Object scopedInstance = scope.get(beanName, () -> {  beforePrototypeCreation(beanName);  try {    return createBean(beanName, mbd, args);  } finally {    afterPrototypeCreation(beanName);  }});

2 自定義Scope

自定義Scope

public class CustomScope implements Scope {      private Object target ;
  @Override  public Object get(String name, ObjectFactory<?> objectFactory) {    return target != null ? target : objectFactory.getObject() ;  }  // 如果調(diào)用了這個方法,那么下次在注入有@Scope("custom")的bean時 將會重寫調(diào)用objectFactory.getObject()方法。  @Override  public Object remove(String name) {    target = null ;    return "success" ;  }
  @Override  public void registerDestructionCallback(String name, Runnable callback) {  }
  @Override  public Object resolveContextualObject(String key) {    return null;  }
  @Override  public String getConversationId() {    return null;  }
}

注冊Scope

@Componentpublic class CustomScopeRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {  @Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {    beanFactory.registerScope("custom", new CustomScope()) ;  }  @Override  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {  }}

使用Scope

@Component@Scope("custom")public class ApplyScopeBean {}

示例

@RestController@RequestMapping("/refresh")@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)public class RefreshController implements ApplicationContextAware{  @Resource  private ApplyScopeBean scopeBean ;  @Resource  private CustomScope customScope ;  @GetMapping("/custom")  public String custom() {    return scopeBean.getCustom() ;  }  @GetMapping("/remove")   public Object remove() {    return customScope.remove("applyScopeBean") ;  }  }

這里將Controller設(shè)置為多例,以便查看效果。交替執(zhí)行上面的接口,只要刪除了就會創(chuàng)建新的實例。

3 多例注入

如果一個Bean 設(shè)置了@Scope(value =
ConfigurableBeanFactory.SCOPE_PROTOTYPE) 當(dāng)這個Bean需要在一個單例Bean中被注入時,需要如下配置才可

@Component@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)public class ApplyScopeBean {}

這樣才能正確地注入Bean,否則因為本身使用者是單例的,屬性只會被初始化一次。也可以在每次使用前調(diào)用BeanFactory#getBean()。

完畢!!!

分享到:
標(biāo)簽:Spring
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定