您可以非常简单地做到这一点。
考虑以下自定义范围类:
package com.way2learn;
import java.util.Map;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
public class MyCustomScope implements Scope{
private Map<String, Object> scope;
public void setScope(Map<String, Object> scope) {
this.scope = scope;
}
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
checkAndClear();
Object bean=scope.get(name);
if(bean==null){
bean=objectFactory.getObject();
scope.put(name,bean);
}
return bean;
}
private void checkAndClear() {
//Some logic to check condition and clear the scope
}
//optional methods
@Override
public Object remove(String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
}
@Override
public Object resolveContextualObject(String key) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getConversationId() {
// TODO Auto-generated method stub
return null;
}
}
它依赖于java.util.Map。
您不能使用@Autowired 自动装配它,因为@Autowired 注释仅在AutoWiredAnnotationBeanPostProcessor 之后有效。
但是自定义范围会在AutoWiredAnnotationBeanPostProcessor之前注册。
因此您可以手动将Map 注入MyCustomScope 类,如下所示:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<util:map key-type="java.lang.String" value-type="java.lang.Object" id="custScopeMap"/>
<bean id="myCustomScope" class="com.way2learn.MyCustomScope">
<property name="scope" ref="custScopeMap"/>
</bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="myScope" value-ref="myCustomScope"/>
</map>
</property>
</bean>
</beans>
我试过了。它工作正常。我在Aaron Digulla's 答案中发现了一个错误,即
考虑以下场景:首先将创建Spring's CustomScopeConfigurer bean,然后立即创建CustomScope bean,现在我们的自定义范围可以使用了。一段时间后,Aaron Digulla's CustomScopeConfigurer 将被创建,它将 foo 初始化为CustomScope。但是如果在CustomScope registration 和Aaron Digulla's CustomScopeConfigurer bean 创建之前创建了一些自定义范围的bean,会发生什么?对于那些 bean,CustomScope bean 中不会有 foo。