package luck.spring;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.SneakyThrows;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorSupport;
import java.lang.reflect.Constructor;
import java.util.*;
@Configuration
public class SpringUtilTest {
@SneakyThrows
public static void main(String[] args) {
// 获取资源文件的工具类
// 获取多语言的工具类
// 获取配置文件的工具类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 获取类元信息工具类
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
// 生成BeanName的工具类
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
String packageName = App.class.getPackage().getName();
String path = StrUtil.format("classpath*:{}/**/*.class", packageName.replace(".", "/"));
// 获取资源文件
// 内部使用的是PathMatchingResourcePatternResolver
Resource[] resources = context.getResources(path);
for (Resource resource : resources) {
// 会将类的信息封装到MetadataReader中
MetadataReader reader = factory.getMetadataReader(resource);
AnnotationMetadata metadata = reader.getAnnotationMetadata();
System.out.println(metadata.hasAnnotation(Component.class.getName()));
// 是否存在派生的注解
System.out.println(metadata.hasMetaAnnotation(Component.class.getName()));
// 注册BeanDefinition
AnnotatedGenericBeanDefinition definition = new AnnotatedGenericBeanDefinition(reader.getAnnotationMetadata());
String beanName = generator.generateBeanName(definition, context);
context.registerBeanDefinition(beanName, definition);
}
System.out.println(Arrays.toString(context.getBeanFactory().getBeanDefinitionNames()));
// JDK自带类型转换工具类
StringToUserPropertyEditor editor = new StringToUserPropertyEditor();
editor.setAsText(User.class.getName());
System.out.println(editor.getValue());
// Spring提供的类型转换器
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToUserConverter());
// 默认先使用JDK的,再使用Spring的
User user = conversionService.convert(User.class.getName(), User.class);
System.out.println(user);
// Spring提供的JDK,Spring提供的上面两种二合一的方式
SimpleTypeConverter converter = new SimpleTypeConverter();
converter.registerCustomEditor(User.class, editor);
converter.setConversionService(conversionService);
// 转换
User u = converter.convertIfNecessary(User.class.getName(), User.class);
System.out.println(u);
}
/**
* 交给Spring管理
*/
@Bean
public ConversionServiceFactoryBean conversionServiceFactoryBean() {
ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
factoryBean.setConverters(Collections.singleton(new StringToUserConverter()));
return factoryBean;
}
/**
* 将自定义的类型转换器交给Spring管理
* CustomEditorConfigurer是一个BeanFactoryPostProcessor
* 它会将自定义个类型转换器交给Spring的BeanFactory中类型转换的时候会从容器中拿出来
*/
@Bean
public CustomEditorConfigurer customEditorConfigurer() {
CustomEditorConfigurer configurer = new CustomEditorConfigurer();
Map<Class<?>, Class<? extends PropertyEditor>> map = new HashMap<>();
map.put(User.class, StringToUserPropertyEditor.class);
configurer.setCustomEditors(map);
return configurer;
}
@Data
@AllArgsConstructor
static class User {
int id;
String name;
}
// Spring提供的类型转换工具
static class StringToUserConverter implements ConditionalGenericConverter {
// 是否转换的符合条件
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return sourceType.getType().equals(String.class) && targetType.getType().equals(User.class);
}
// 可以提供类型转换的"类型对",多个
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class, User.class));
}
// 类型转换
@SneakyThrows
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
System.out.println("Spring的转换器");
Class<?> aClass = Class.forName(String.valueOf(source));
Constructor<?> constructor = aClass.getDeclaredConstructor(int.class, String.class);
Object user = constructor.newInstance(200, "luck");
return user;
}
}
// java提供的类型转换工具
static class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor {
@SneakyThrows
@Override
public void setAsText(String text) throws IllegalArgumentException {
System.out.println("JDK的转换器");
Class<?> aClass = Class.forName(text);
Constructor<?> constructor = aClass.getDeclaredConstructor(int.class, String.class);
Object user = constructor.newInstance(200, "luck");
this.setValue(user);
}
}
}
02-08
185
06-25
7619
05-23
06-06
798
05-01
1万+
04-30