管理Springbeans创建和字典
我必须管理bean实例和某种类型的资源之间的关联。更具体地说,当我接收到与资源A相关联的一些数据时,每次我接收到与指定资源相关联的数据时,我都必须将数据分派给CREATEA,以创建某个bean类型的实例。例如,如果我收到一些与资源“a”关联的数据,那么我必须将这些数据分派给与“a”关联的Bean实例。如果没有与资源“a”关联的Bean实例,那么必须创建它。资源的数量不是静态已知的,只有在执行期间才知道 我知道我需要某种类型的字典来存储资源id和bean实例之间的关联,构建类似于工厂的东西来管理bean的创建。管理Springbeans创建和字典,spring,spring-bean,Spring,Spring Bean,我必须管理bean实例和某种类型的资源之间的关联。更具体地说,当我接收到与资源A相关联的一些数据时,每次我接收到与指定资源相关联的数据时,我都必须将数据分派给CREATEA,以创建某个bean类型的实例。例如,如果我收到一些与资源“a”关联的数据,那么我必须将这些数据分派给与“a”关联的Bean实例。如果没有与资源“a”关联的Bean实例,那么必须创建它。资源的数量不是静态已知的,只有在执行期间才知道 我知道我需要某种类型的字典来存储资源id和bean实例之间的关联,构建类似于工厂的东西来管理b
我如何在春天实现这一点?正确的方法是什么?可以用这种“字典”方式引用Spring
ApplicationContext
。也就是说,您向应用程序上下文指定“设置”资源bean。然后通过map
对象映射“接收到的数据”,该对象反过来持有对bean的引用。一旦数据映射到bean,就可以检索bean并处理接收到的数据。这里有一个简单的例子
这是一个资源服务接口
package de.incompleteco.spring.service;
public interface ResourceService {
public void processData(Object data);
}
下面是一个处理“TypeA”数据的实现
package de.incompleteco.spring.service;
public class TypeAResourceService implements ResourceService {
public void processData(Object data) {
//do something for 'type A' data
}
}
这里有一个“委托”服务
package de.incompleteco.spring.service;
import java.util.Map;
import de.incompleteco.spring.domain.TypeA;
import de.incompleteco.spring.domain.TypeB;
public class DelegateResourceService implements ResourceService {
private Map<String,ResourceService> services;
public void processData(Object data) {
if (data instanceof TypeA) {
services.get(TypeA.class.getSimpleName()).processData(data);
} else if (data instanceof TypeB) {
services.get(TypeA.class.getSimpleName()).processData(data);
} else {
throw new IllegalArgumentException("...");
}
}
public void setServices(Map<String, ResourceService> services) {
this.services = services;
}
}
package de.incompleteco.spring.service;
导入java.util.Map;
导入de.incompleteco.spring.domain.TypeA;
导入de.incompleteco.spring.domain.TypeB;
公共类DelegateResourceService实现ResourceService{
私人地图服务;
公共void processData(对象数据){
if(类型A的数据实例){
getservices.get(TypeA.class.getSimpleName()).processData(data);
}else if(类型B的数据实例){
getservices.get(TypeA.class.getSimpleName()).processData(data);
}否则{
抛出新的IllegalArgumentException(“…”);
}
}
公共void设置服务(地图服务){
这是服务=服务;
}
}
“委托”服务负责从映射中检索正确的服务以处理正确的数据(按类名键入)
下面是要支持的spring配置
<?xml version="1.0" encoding="UTF-8"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- type 'a' bean -->
<bean id="typeA" class="de.incompleteco.spring.service.TypeAResourceService"/>
<!-- type 'b' bean -->
<bean id="typeB" class="de.incompleteco.spring.service.TypeBResourceService"/>
<util:map id="dictionary">
<entry key="TypeA" value-ref="typeA"/>
<entry key="TypeB" value-ref="typeB"/>
</util:map>
<bean class="de.incompleteco.spring.service.DelegateResourceService">
<property name="services" ref="dictionary"/>
</bean>
</beans>
此配置执行以下操作:
- 为类型A和B数据设置服务
- 将这些服务映射到密钥
- 设置代理服务,设置要使用的映射
- 能够独立地配置服务bean
- 代理只需要一个映射即可进行处理
- 约束条件是服务对象必须具有相同的接口
您可以将Spring ApplicationContext视为一个巨大的工厂,但(在许多方面)设置起来要简单得多。mmmmm谢谢您的建议,但有一个问题:我不知道静态情况下我将获得哪些资源。不要以类型化的方式思考资源(
TypeA
,TypeB
),而是以基于动态值的方式思考资源(resource.getValue()==“a”
,resource.getValue()==“b”
,其中可能的值未知)。通过这种方式,我无法在配置文件中指定映射值,但我需要类似以下内容:if(!map.contains(resource.getValue())createDelegate(resource);
。如果键的数量是无限的,则缓存会导致内存泄漏;如果键的数量是常数,则可以查看对象的数量并在之前创建bean。如果存在(类似散列的)将密钥投影到某个较小的有限密钥集的函数可能会起作用,但无论如何,通过创建单独的bean进行缓存对我来说似乎很奇怪。我想你应该将缓存移到某个较低级别的抽象,并使用spring缓存功能,而不是创建bean。即缓存服务返回的一些DTO或实体当然,bean将是有限的,并且与应用程序交互的用户数量将更少(使用每个会话范围的bean将导致更多的bean)。