Spring最早是通过xml方式注入bean,但是xml文件本质是字符串,所以可想而知,底层spring是做了类型转换。
一、PropertyEditor需要注意这个接口是jdk提供的接口,并非Spring提供的
1.1、继承PropertyEditorSupportpublic class StringToObject extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { if (text.startsWith("mem.")) {//需要以mem.开始字符串才可以 MemberService service = new MemberService(); service.setClusterName(text.substring(4)); this.setValue(service); } } }1.2、注入CustomEditorConfigurer
定义好转换器后,需要作为bean注入到spring容器中,spring提供了一个类,用于收集所有的转换器,具体如下
@Configuration public class AppConfig { @Bean public CustomEditorConfigurer getCustomPropertyToBean() { CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer(); Map1.3、应用, Class extends PropertyEditor>> customEditors = new HashMap<>(); customEditors.put(MemberService.class, StringToObject.class); customEditorConfigurer.setCustomEditors(customEditors); return customEditorConfigurer; } }
@Component public class UserService { @Value("mem.beijingCluster") //字符串 转成 MemberService对象 private MemberService memberService; public UserService() { System.out.println("UserService constructor"); } @Override public String toString() { return "UserService{" + "memberService=" + memberService + '}'; } }
public class App { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.example"); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); } } //输出结果: // UserService{memberService=MemberService{clusterName='beijingCluster'}} //二、接口ConditionalGenericConverter
Spring提供有条件转换器,功能更强大一些,但是有一点需要注意:注入Bean的名字必须是conversionService否则不能注入。
public class CustomConvertService implements ConditionalGenericConverter { @Override public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return sourceType.getType().equals(String.class) && targetType.getType().equals(MemberService.class); } @Override public SetgetConvertibleTypes() { Set set = new HashSet<>(); ConvertiblePair pair = new ConvertiblePair(String.class, MemberService.class); set.add(pair); return set; } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (targetType.getType() == MemberService.class) { MemberService service = new MemberService(); service.setClusterName((String)source); return service; } return null; } }
@Configuration public class AppConfig { //注意这里的名字 方法名字必须是conversionService,否则不能注入 @Bean public ConversionServiceFactoryBean conversionService() { ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean(); bean.setConverters(Collections.singleton(new CustomConvertService())); return bean; } }
@Component public class UserService { @Value("mem.beijingCluster") private MemberService memberService; public UserService() { } @Override public String toString() { return "UserService{" + "memberService=" + memberService + '}'; } } public class App { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.example"); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); } }三、总结
通过上面总结,我们完全可以自定义类型转换器,完成更为复杂的业务处理,比如说json的转换。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)