栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring源码学习笔记(4)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring源码学习笔记(4)

 类型转化   在Spring源码中,有可能需要把String转成其他类型,所以在Spring源码中提供了一些技术来更方便的做对象的类型转化,关于类型转化的应用场景, 后续看源码的过程中会遇到很多。 PropertyEditor 这其实是JDK中提供的类型转化工具类 假设现在有如下Bean: @Component public class UserService { @Value("xxx") private User user; public void test() {System.out.println(user); } } 那么test属性就能正常的完成属性赋值 ConversionService Spring中提供的类型转化服务,它比PropertyEditor更强大 public 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 getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(String.class, User.class)); } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { User user = new User(); user.setName((String)source); return user; } } DefaultConversionService conversionService = new DefaultConversionService(); conversionService.addConverter(new StringToUserConverter()); User value = conversionService.convert("1", User.class); System.out.println(value); 如何向Spring中注册ConversionService: @Bean public ConversionServiceFactoryBean conversionService() { ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean(); conversionServiceFactoryBean.setConverters(Collections.singleton(new StringToUserConverter())); return conversionServiceFactoryBean; } TypeConverterTypeConverter 整合了PropertyEditor和ConversionService的功能,是Spring内部用的SimpleTypeConverter typeConverter = new SimpleTypeConverter(); typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor()); User value = typeConverter.convertIfNecessary("1", User.class); System.out.println(value); OrderComparator OrderComparator是Spring所提供的一种比较器,可以用来根据@Order注解或实现Ordered接口 来执行值进行笔记,从而可以进行排序。 比如: public class A implements Ordered { @Override public int getOrder() { return 3; } @Override public String toString() { return this.getClass().getSimpleName(); } } public class B implements Ordered { @Override public int getOrder() { return 2; } @Override public String toString() { return this.getClass().getSimpleName(); } } public class Main { public static void main(String[] args) {A a = new A(); // order=3 B b = new B(); // order=2 OrderComparator comparator = new OrderComparator(); System.out.println(comparator.compare(a, b)); // 1 List list = new ArrayList<>(); list.add(a); list.add(b); // order值升序排序 list.sort(comparator); System.out.println(list); // BA } } 一个BeanPostProcessor可以在任意一个Bean的初始化之前以及初始化之后去额外的做一些用户自定义的逻辑,当然,我们可以通过判断beanName来进行针对性处理(针对某个Bean,或某部分Bean)。 我们可以通过定义BeanPostProcessor来干涉Spring创建Bean的过程。 BeanFactoryPostProcessor BeanFactoryPostProcessor表示Bean工厂的后置处理器,其实和BeanPostProcessor类似, BeanPostProcessor是干涉Bean的创建过程,BeanFactoryPostProcessor是干涉BeanFactory的创 建过程。比如,我们可以这样定义一个BeanFactoryPostProcessor: @Component public class ZhouyuBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("加工beanFactory"); } } 我们可以在postProcessBeanFactory()方法中对BeanFactory进行加工。 FactoryBean 上面提到,我们可以通过BeanPostPorcessor来干涉Spring创建Bean的过程,但是如果我们想一个 Bean完完全全由我们来创造,也是可以的,比如通过FactoryBean: @Component public class ZhouyuFactoryBean implements FactoryBean { @Override public Object getObject() throws Exception { UserService userService = new UserService(); return userService; } @Override public Class getObjectType() { return UserService.class; } } 通过上面这段代码,我们自己创造了一个UserService对象,并且它将成为Bean。但是通过这种方式创造出来的UserService的Bean,只会经过初始化后,其他Spring的生命周期步骤是不会经过的,比如依赖注入。 ExcludeFilter和IncludeFilter 这两个Filter是Spring扫描过程中用来过滤的。ExcludeFilter表示排除过滤器,IncludeFilter表示包 含过滤器。 比如以下配置,表示扫描com.zhouyu这个包下面的所有类,但是排除UserService类,也就是就算 它上面有@Component注解也不会成为Bean。 @ComponentScan(value = "com.zhouyu", excludeFilters = {@ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)}.) public class AppConfig { } 再比如以下配置,就算UserService类上没有@Component注解,它也会被扫描成为一个Bean。 @ComponentScan(value = "com.zhouyu", includeFilters = {@ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)}) public class AppConfig { } FilterType分为: 1. ANNOTATION:表示是否包含某个注解 2. ASSIGNABLE_TYPE:表示是否是某个类 3. ASPECTJ:表示否是符合某个Aspectj表达式 4. REGEX:表示是否符合某个正则表达式 5. CUSTOM:自定义 在Spring的扫描逻辑中,默认会添加一个AnnotationTypeFilter给includeFilters,表示默认情况下 Spring扫描过程中会认为类上有@Component注解的就是Bean。 metadataReader、Classmetadata、 Annotationmetadata 在Spring中需要去解析类的信息,比如类名、类中的方法、类上的注解,这些都可以称之为类的元数据,所以Spring中对类的元数据做了抽象,并提供了一些工具类。 metadataReader表示类的元数据读取器,默认实现类为SimplemetadataReader。比如: public class Test { public static void main(String[] args) throws IOException { SimplemetadataReaderFactory simplemetadataReaderFactory = new SimplemetadataReaderFactory(); // 构造一个metadataReader metadataReader metadataReader =simplemetadataReaderFactory.getmetadataReader("com.zhouyu.service.UserService"); // 得到一个Classmetadata,并获取了类名 Classmetadata classmetadata = metadataReader.getClassmetadata(); System.out.println(classmetadata.getClassName()); // 获取一个Annotationmetadata,并获取类上的注解信息 Annotationmetadata annotationmetadata = metadataReader.getAnnotationmetadata(); for (String annotationType : annotationmetadata.getAnnotationTypes()) { System.out.println(annotationType); } } } 需要注意的是,SimplemetadataReader去解析类时,使用的ASM技术。 为什么要使用ASM技术,Spring启动的时候需要去扫描,如果指定的包路径比较宽泛,那么扫描的 类是非常多的,那如果在Spring启动时就把这些类全部加载进JVM了,这样不太好,所以使用了 ASM技术。  

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/667555.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号