[SPRING] 봄 부팅으로 프로그래밍 방식으로 스프링 변환기 등록
SPRING봄 부팅으로 프로그래밍 방식으로 스프링 변환기 등록
스프링 부트 프로젝트에 스프링 변환기를 프로그래밍 방식으로 등록하려고합니다. 지난 봄 프로젝트에서 저는 XML로 이렇게했습니다 ...
<!-- Custom converters to allow automatic binding from Http requests parameters to objects -->
<!-- All converters are annotated w/@Component -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<ref bean="stringToAssessmentConverter" />
</list>
</property>
</bean>
스프링 부트의 SpringBootServletInitializer에서 수행하는 방법을 파악하려고합니다.
업데이트 : StringToAssessmentConverter를 getConversionService의 인수로 전달하여 약간의 진전을 이루었습니다. 그러나 이제 StringToAssessmentConverter 클래스에 대해 "기본 생성자가 없습니다"오류가 발생합니다. 왜 Spring이 @Autowired 생성자를 보지 못하고 있는지 모르겠습니다.
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
...
@Bean(name="conversionService")
public ConversionServiceFactoryBean getConversionService(StringToAssessmentConverter stringToAssessmentConverter) {
ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
Set<Converter> converters = new HashSet<>();
converters.add(stringToAssessmentConverter);
bean.setConverters(converters);
return bean;
}
}
변환기에 대한 코드는 다음과 같습니다.
@Component
public class StringToAssessmentConverter implements Converter<String, Assessment> {
private AssessmentService assessmentService;
@Autowired
public StringToAssessmentConverter(AssessmentService assessmentService) {
this.assessmentService = assessmentService;
}
public Assessment convert(String source) {
Long id = Long.valueOf(source);
try {
return assessmentService.find(id);
} catch (SecurityException ex) {
return null;
}
}
}
전체 오류
Failed to execute goal org.springframework.boot:spring-boot-maven-
plugin:1.3.2.RELEASE:run (default-cli) on project yrdstick: An exception
occurred while running. null: InvocationTargetException: Error creating
bean with name
'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPo
stProcessor': Invocation of init method failed; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error
creating bean with name 'conversionService' defined in
me.jpolete.yrdstick.Application: Unsatisfied dependency expressed through
constructor argument with index 0 of type
[me.jpolete.yrdstick.websupport.StringToAssessmentConverter]: : Error
creating bean with name 'stringToAssessmentConverter' defined in file
[/yrdstick/target/classes/me/jpolete/yrdstick/websupport
/StringToAssessmentConverter.class]: Instantiation of bean failed; nested
exception is org.springframework.beans.BeanInstantiationException: Failed
to instantiate
[me.jpolete.yrdstick.websupport.StringToAssessmentConverter]: No default
constructor found; nested exception is java.lang.NoSuchMethodException:
me.jpolete.yrdstick.websupport.StringToAssessmentConverter.<init>();
nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'stringToAssessmentConverter' defined in file [/yrdstick
/dev/yrdstick/target/classes/me/jpolete/yrdstick/websupport
/StringToAssessmentConverter.class]: Instantiation of bean failed; nested
exception is org.springframework.beans.BeanInstantiationException: Failed
to instantiate
[me.jpolete.yrdstick.websupport.StringToAssessmentConverter]: No default
constructor found; nested exception is java.lang.NoSuchMethodException:
me.jpolete.yrdstick.websupport.StringToAssessmentConverter.<init>()
해결법
-
==============================
1.대답은 변환기를 @Component로 주석 달기 만하면됩니다.
대답은 변환기를 @Component로 주석 달기 만하면됩니다.
이것은 나의 변환기 예제이다.
import org.springframework.core.convert.converter.Converter; @Component public class DateUtilToDateSQLConverter implements Converter<java.util.Date, Date> { @Override public Date convert(java.util.Date source) { return new Date(source.getTime()); } }
그리고 나서 Spring이 변환을해야 할 때, 변환기가 호출된다.
내 봄 부팅 버전 : 1.4.1
-
==============================
2.여기 내 해결책은 다음과 같습니다.
여기 내 해결책은 다음과 같습니다.
TypeConverter 주석 :
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface TypeConverter { }
변환기 등록자 :
@Configuration public class ConverterConfiguration { @Autowired(required = false) @TypeConverter private Set<Converter<?, ?>> autoRegisteredConverters; @Autowired(required = false) @TypeConverter private Set<ConverterFactory<?, ?>> autoRegisteredConverterFactories; @Autowired private ConverterRegistry converterRegistry; @PostConstruct public void conversionService() { if (autoRegisteredConverters != null) { for (Converter<?, ?> converter : autoRegisteredConverters) { converterRegistry.addConverter(converter); } } if (autoRegisteredConverterFactories != null) { for (ConverterFactory<?, ?> converterFactory : autoRegisteredConverterFactories) { converterRegistry.addConverterFactory(converterFactory); } } } }
그런 다음 변환기에 주석을 추가하십시오.
@SuppressWarnings("rawtypes") @TypeConverter public class StringToEnumConverterFactory implements ConverterFactory<String, Enum> { @SuppressWarnings("unchecked") public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) { return new StringToEnum(targetType); } private final class StringToEnum<T extends Enum> implements Converter<String, T> { private Class<T> enumType; public StringToEnum(Class<T> enumType) { this.enumType = enumType; } @SuppressWarnings("unchecked") public T convert(String source) { return (T) Enum.valueOf(this.enumType, source.trim().toUpperCase()); } } }
-
==============================
3.이 시도:
이 시도:
@SpringBootApplication public class Application extends SpringBootServletInitializer { @Bean public AssessmentService assessmentService(){ return new AssessmentService(); } @Bean public StringToAssessmentConverter stringToAssessmentConverter(){ return new StringToAssessmentConverter(assessmentService()); } @Bean(name="conversionService") public ConversionService getConversionService() { ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean(); Set<Converter> converters = new HashSet<Converter>(); //add the converter converters.add(stringToAssessmentConverter()); bean.setConverters(converters); return bean.getObject(); } // separate these class into its own java file if necessary // Assesment service class AssessmentService {} //converter class StringToAssessmentConverter implements Converter<String, Assessment> { private AssessmentService assessmentService; @Autowired public StringToAssessmentConverter(AssessmentService assessmentService) { this.assessmentService = assessmentService; } public Assessment convert(String source) { Long id = Long.valueOf(source); try { return assessmentService.find(id); } catch (SecurityException ex) { return null; } } } }
또는 StringToAssessmentConverter가 이미 스프링 빈인 경우 :
@Autowired @Bean(name="conversionService") public ConversionService getConversionService(StringToAssessmentConverter stringToAssessmentConverter) { ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean(); Set<Converter> converters = new HashSet<Converter>(); //add the converter converters.add(stringToAssessmentConverter); bean.setConverters(converters); return bean.getObject(); }
from https://stackoverflow.com/questions/35025550/register-spring-converter-programmatically-in-spring-boot by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄 : 최대 절전 모드 + ehcache (0) | 2019.03.28 |
---|---|
[SPRING] 스프링 MVC 3을 사용하여 물음표 대신 악센트 부호가있는 문자 가져 오기 (0) | 2019.03.27 |
[SPRING] 게시 구독 주제에 대한 @JmsListener 사용 (0) | 2019.03.27 |
[SPRING] Spring 데이터 Rest 컨트롤러 : @BasePathAwareController, @RepositoryRestController, @Controller 및 @RestController의 동작 및 사용법 (0) | 2019.03.27 |
[SPRING] 최대 절전 모드로 C3P0의 스프링 구성? (0) | 2019.03.27 |