环境:spring5.3.31Scope函数通过@Scope注解可以指定bean的作用域。默认是单例(ConfigurableBeanFactory.SCOPE_SINGLETON=singleton)。创建bean实例时,根据当前BeanDefinition中的Scope不同创建,源码如下:protectedTdoGetBean(Stringname,@NullableClassrequiredType,@NullableObject[]args,booleantypeCheckOnly)throwsBeansException{StringbeanName=transformedBeanName(name);Objectbean;//Eagerlychecksingletoncacheformanuallyregisteredsingletons.Objectbeaninstance=getSingle);if(sharedInstance!=null&&args==null){//othercode}else{//othercodetry{RootBeanDefinitionmbd=getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinitionmbd,beanName,args);//Guaranteeinitializationofbeansthatthecurrentbeanddependson.//otherincode/st.Create//根据BeanDefinition中定义的Scope创建实例//判断是否是单例if(mbd.isSingleton()){//如果它是一个单例Bean,Bean会被保存在缓存中singletonObjectssharedInstance=getSingleton(beanName,()->{try{returncreateBean(beanName,mbd,args);}catch(BeansExceptionex){destroySingleton(beanName);throwex;}});bean=getObjectForBeanInstance(sharedInstance,name,beanName,mbd);}//判定如果是原型(多个例子)elseif(mbd.isPrototype()){//它'saprototype->createanewinstance.ObjectprototypeInstance=null;try{beforePrototypeCreation(beanName);prototypeInstance=createBean(beanName,mbd,args);}finally{afterPrototypeCreation(beanName);}bean=getObjectForBeanInstance(prototypeInstance,name,beanName,mbd);}else{StringscopeName=mbd.getScope();if(!StringUtils.hasLength(scopeName)){thrownewIllegalStateException("Noscopenamedefinedforbean"+beanName+"'");}Scopescope=this.scopes.get(scopeName);//当集合中也不存在时抛出异常if(scope==null){thrownewIllegalStateException("NoScoperegisteredforscopename'"+scopeName+"'");}try{ObjectscopedInstance=scope.get(beanName,()->{beforePrototypeCreation(beanName);try{returncreateBean(beanName,mbd,args);}finally{afterPrototypeCreation(beanName);}});bean=getObjectForBeanInstance(scopedInstance,name,beanName,mbd);}catch(IllegalStateExceptionex){thrownewBeanCreationException(beanName,"Scope'"+scopeName+"'isnotactiveforthecurrentthread;考虑"+"definingascopedproxyforthisbeanifyyouintendtorefertoitcleasefromasingleton",ex);}}}CreationBeansExceptionAcatch(BeansExceptionA(beanName);throwex;}}//othercodereturn(T)bean;}从上面源码判断是否是Singleton和Proptotype,如果不是,则从Mapscopes中获取,如果你当前配置的@Scope不是单例和原型,所以是从scopes集合中取的(这个集合是通过AbstractBeanFactory#registerScope方法注册的,一般我们可以通过BeanDefinitionRegistryPostProcessor注册),如果集合中不存在,将抛出异常。如果存在,就会执行Scope#get方法);}finally{afterPrototypeCreation(beanName);}});2CustomScopeCustomScopepublicclassCustomScopeimplementsScope{privateObjecttarget;@OverridepublicObjectget(Stringname,ObjectFactory>objectFactory){returntarget!=null?target:objectFactory.getObject();}//如果调用此方法,则下次注入带有@Scope("custom")的bean时将重写objectFactory.getObject()方法。@OverridepublicObjectremove(Stringname){target=null;return"success";}@OverridepublicvoidregisterDestructionCallback(Stringname,Runnablecallback){}@OverridepublicObjectresolveContextualObject(Stringkey){returnnull;}@OverridepublicStringgetConversationId(){returnnull;}}注册Scope@ComponentpublicclassCustomScopeRegistryPostProcessorimplementsBeanDefinitionRegistryPostProcessor{@OverridepublicvoidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory)throwsBeansException{beanFactory.registerScope("custom",newCustomScope());}@OverridepublicvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistryregistry)throwsBeansException{}}使用Scope@Component@Scope("custom")publicclassApplyScopeBean{}示例@RestController@RequestMapping("/refresh")@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)publicclassRefreshControllerimplementsApplicationContextAware{@ResourceprivateApplyScopeBeanscopeBean;@ResourceprivateCustomScopecustomScope;@GetMapping("/custom")publicStringcustom(){returnscopeBean.getCustom();}@GetMapping("/remove")publicObjectremove(){returncustomScope.remove("applyScopeBean");}}这里控制器设置为多个实例,为了查看效果交替执行上面的接口,只要删除了,就会创建一个新的实例。3多重注入如果一个Bean设置了@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)当这个Bean需要在单例Bean中注入时,需要如下配置@Component@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE,proxyMode=ScopedProxyMode.TARGET_CLASS)publicclassApplyScopeBean{}只有这样才能正确注入bean。否则因为用户本身是单例,所以属性只会被初始化一次。也可以在每次使用前调用BeanFactory#getBean()。