Java 将ConversionService注入自定义转换器
使用SpringMVC-3。我正在编写一个自定义转换器,它需要访问注册到ConversionService的其他转换器 我怎样才能做到这一点?我尝试将自定义转换器编写为:Java 将ConversionService注入自定义转换器,java,spring,spring-mvc,Java,Spring,Spring Mvc,使用SpringMVC-3。我正在编写一个自定义转换器,它需要访问注册到ConversionService的其他转换器 我怎样才能做到这一点?我尝试将自定义转换器编写为: class CustomConverter<X, Y>{ @Autowired ConversionService service; //+getter & setters of service public Y convert(X input){ /
class CustomConverter<X, Y>{
@Autowired ConversionService service;
//+getter & setters of service
public Y convert(X input){
// I need access to service to lookup simple conversions such as
// String array to Long array etc..
}
}
类自定义转换器{
@自动连线转换服务;
//+服务的接受者和接受者
公共Y转换(X输入){
//我需要访问服务来查找简单的转换,例如
//字符串数组到长数组等。。
}
}
我通过applicationContext.xml注册了自定义转换器
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name = "converters">
<list>
<bean class="CustomConverter"/>
</list>
</property>
</bean>
然而,spring拒绝将服务注入我的CustomConverter(它总是空的)。我怎样才能做到这一点
谢谢大家! 我最近用了类似的方法来解决这个问题。 使用自定义工厂:
public class MyConversionServiceFactoryBean extends ConversionServiceFactoryBean {
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
ConversionService conversionService = getObject();
ConverterRegistry registry = (ConverterRegistry) conversionService;
// register converters that need a nested conversion service
registry.addConverter(new MyCustomConverter(conversionService));
}
}
声明如下:
<bean id="conversionService"
class="com.company.MyConversionServiceFactoryBean">
<property name="converters">
<list>
... declare standard converters here ...
</list>
</property>
</bean>
... 在这里声明标准转换器。。。
我也遇到了同样的问题。春天有一个关于这个问题的杂志。我在这里根据对这个问题的讨论给出了我的解决方案。这与@NMervailie的答案相同,但您不必实现自己的转换ServiceFactoryBean
/**
* Base class of @{code Converter} that need to use {@code ConversionService}.
* Instances of implementing classes must be spring-managed to inject ConversionService.
*
* @author Michal Kreuzman
*/
public abstract class CoversionServiceAwareConverter<S, T> implements Converter<S, T> {
@Inject
private ConversionService conversionService;
protected ConversionService conversionService() {
return conversionService;
}
/**
* Add this converter to {@code ConverterRegistry}.
*/
@SuppressWarnings("unused")
@PostConstruct
private void register() {
if (conversionService instanceof ConverterRegistry) {
((ConverterRegistry) conversionService).addConverter(this);
} else {
throw new IllegalStateException("Can't register Converter to ConverterRegistry");
}
}
}
@Component
public class SampleConverter extends CoversionServiceAwareConverter<Object, Object> {
@Override
public String convert(Object source) {
ConversionService conversionService = conversionService();
// Use conversionService and convert
}
}
/**
*需要使用{@code ConversionService}的{code Converter}基类。
*实现类的实例必须由spring管理以注入ConversionService。
*
*@作者Michal Kreuzman
*/
公共抽象类CoversionServiceAwarConverter实现转换器{
@注入
私有转换服务转换服务;
受保护的转换服务转换服务(){
返回转换服务;
}
/**
*将此转换器添加到{@code ConverterRegistry}。
*/
@抑制警告(“未使用”)
@施工后
私人无效登记册(){
if(ConverterRegistry的转换服务实例){
((ConverterRegistry)conversionService).addConverter(this);
}否则{
抛出新的IllegalStateException(“无法将转换器注册到ConverterRegistry”);
}
}
}
@组成部分
公共类SampleConverter扩展CoversionServiceAwarConverter{
@凌驾
公共字符串转换(对象源){
ConversionService ConversionService=ConversionService();
//使用conversionService和convert
}
}
主要问题(我遇到过)当您使用ConversionServiceFactoryBean
构建转换服务
时,也包括使用转换服务
的转换器,因为ConversionServiceFactoryBean而导致错误。提供转换服务
实例的getObject
方法在前面被调用到实际创建转换服务实例的ConversionServiceFactoryBean.afterPropertiesSet
因此,为了避免这种行为,您只需要在转换服务工厂bean之前创建转换服务
。我在类的构造函数中创建了它,该类扩展了转换服务工厂bean
。
例如:
try {
Field serviceField = ConversionServiceFactoryBean.class.getDeclaredField("conversionService");
conversionServiceField.setAccessible(true);
conversionServiceField.set(this, createConversionService());
} catch (NoSuchFieldException | IllegalAccessException fieldAccessError) {
fieldAccessError.printStackTrace();
//or do some log output here, it's up to you
}
您还可以使用使用转换服务的转换器。
希望有帮助。我在spring ws-centric应用程序中解决了这个问题。该解决方案的主要组成部分包括:
- 将转换器实现声明为Springbean
- 在转换器的注入点上使用@Lazy from spring上下文
- 将发现的所有转换器注入到ConversionServiceFactoryBean中
采样转换器
@Component
public class SampleConverter implements Converter<Source, Target> {
private ConversionService conversionService;
@Inject
@Lazy
public SampleConverter(ConversionService conversionService){
this.conversionService = conversionService;
}
@Override
public Target convert(Source source){
Target target = new Target();
...
target.setTargetDetails(conversionService.convert(source.getSourceDetails, TargetDetails.class);
...
@组件
公共类SampleConverter实现转换器{
私有转换服务转换服务;
@注入
@懒惰的
公共样本转换器(转换服务转换服务){
this.conversionService=conversionService;
}
@凌驾
公共目标转换(源){
目标=新目标();
...
target.setTargetDetails(conversionService.convert(source.getSourceDetails,TargetDetails.class));
...
以及配置:
@Configuration
public class ConversionServiceConfig {
@Bean
public ConversionService conversionService(Set<Converter<?,?>> converters){
ConversionServiceFactoryBean csfb = new ConversionServiceFactoryBean();
csfb.setConverters(converters);
csfb.afterPropertiesSet();
return csfb.getObject();
}
@配置
公共类转换服务配置{
@豆子
公共转换服务转换服务(SetI)得出了相同的结论!谢谢。这个解决方案的问题是MyCustomConverter不是由spring容器管理的