스프링 부트에 스프링 컨버터를 프로그래밍 방식으로 등록
스프링 컨버터를 프로그래밍 방식으로 스프링 부트 프로젝트에 등록하려고 합니다.과거 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>
SpringBoot의 SpringBoot Servlet에서 하는 방법을 찾고 있습니다.이니셜라이저
업데이트: StringToAssessmentConverter를 인수로 전달하여 약간의 진전을 이루었습니다.getConversionService
하지만 지금 나는"No default constructor found"
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>()
정답은 변환기에 다음과 같이 주석을 달면 된다는 것입니다.@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
제 솔루션은 다음과 같습니다.
유형 변환기 주석:
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface TypeConverter {
}
Converter Registrar:
@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());
}
}
}
**@Component(및 유사한 고정관념 주석)로 주석이 달린 변환기의 자동 등록이 수행되는 Spring Boot에 있지 않고 Web MVC 환경에 있지 않은 경우:
@Bean
ConversionService conversionService(){
ConversionServiceFactoryBean factory = new ConversionServiceFactoryBean();
Set<Converter<?, ?>> convSet = new HashSet<Converter<?, ?>>();
convSet.add(new MyConverter()); // or reference bean convSet.add(myConverter());
factory.setConverters(convSet);
factory.afterPropertiesSet();
return factory.getObject();
}
사용해 보십시오.
@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();
}
스프링 부트의 경우 다음과 같습니다.
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
// do not replace with lambda as spring cannot determine source type <S> and target type <T>
registry.addConverter(new Converter<String, Integer>() {
@Override
public Integer convert(String text) {
if (text == null) {
return null;
}
String trimmed = StringUtils.trimWhitespace(text);
return trimmed.equals("null") ? null : Integer.valueOf(trimmed);
}
});
}
또한 xml 구성에서 사용자 지정 변환기를 등록하는 데 문제가 있었습니다.변환기 ID를 주석 드라이버에 추가해야 합니다.
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="ru.javawebinar.topjava.util.StringToLocalDateConverter"/>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"/>
참조 링크: Spring MVC. 유형 변환, 스프링 코어. 유형 변환
속성을 구성 요소로 등록하는 특정 개체로 변환하는 데 변환기가 필요한 경우 너무 늦을 수 있습니다.spring-boot-2.3.11을 사용하고 있는데 오류가 발생합니다.No converter found capable of converting from type [java.lang.String] to type [org.raisercostin.jedio.WritableDirLocation]
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'revobet.feed.lsports.rest.dump-dir' to org.raisercostin.jedio.WritableDirLocation:
Property: myapp.dump-dir
Value: file://localhost/C:\Users\raiser/.myapp/cache
Origin: class path resource [myapp.conf]:-1:1
Reason: No converter found capable of converting from type [java.lang.String] to type [org.raisercostin.jedio.WritableDirLocation]
Action:
Update your application's configuration
해결책
public class MyApp implements ApplicationRunner {
public static void main(String[] args) {
LocationsConverterConfig.init();
SpringApplication.run(MyApp.class, args);
}
}
및 변환기
public class LocationsConverterConfig {
public static void init() {
ApplicationConversionService conversionService = (ApplicationConversionService) ApplicationConversionService
.getSharedInstance();
log.info("adding JacksonStringToObjectConverter to handle Locations serialization as soon as possible");
conversionService.addConverter(new JacksonStringToObjectConverter());
}
//@Component
public static class JacksonStringToObjectConverter implements ConditionalGenericConverter {
public JacksonStringToObjectConverter() {
log.info("adding {} to handle Locations serialization as soon as possible", JacksonStringToObjectConverter.class);
}
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Object.class, Object.class));
}
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return true;
}
@Override
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
...
}
}
}
언급URL : https://stackoverflow.com/questions/35025550/register-spring-converter-programmatically-in-spring-boot
'programing' 카테고리의 다른 글
해시 각 루프에서 인덱스에 액세스할 수 있습니까? (0) | 2023.07.10 |
---|---|
C#의 XLSX에서 데이터 읽기 (0) | 2023.07.10 |
WordPress 콜백 함수에서 게시 메타 가져오기 (0) | 2023.07.10 |
[표시]를 사용하여 표시하는 방법자동 완성 재료2의 경우 (0) | 2023.07.10 |
data.목록에 대한 행 프레임 (0) | 2023.07.10 |