17. 数据类型转换工厂设计实现
17. 数据类型转换工厂设计实现
工程结构
lqf-spring-step-17
├── main
│ ├── java
│ │ └── lqf
│ │ └── springframework
│ │ ├── aop
│ │ │ ├── AdvisedSupport.java
│ │ │ ├── Advisor.java
│ │ │ ├── BeforeAdvice.java
│ │ │ ├── ClassFilter.java
│ │ │ ├── MethodBeforeAdvice.java
│ │ │ ├── MethodMatcher.java
│ │ │ ├── Pointcut.java
│ │ │ ├── PointcutAdvisor.java
│ │ │ ├── TargetSource.java
│ │ │ ├── aspectj
│ │ │ │ ├── AspectJExpressionPointcut.java
│ │ │ │ └── AspectJExpressionPointcutAdvisor.java
│ │ │ └── framework
│ │ │ ├── AopProxy.java
│ │ │ ├── Cglib2AopProxy.java
│ │ │ ├── JdkDynamicAopProxy.java
│ │ │ ├── ProxyFactory.java
│ │ │ ├── ReflectiveMethodInvocation.java
│ │ │ ├── adapter
│ │ │ │ └── MethodBeforeAdviceInterceptor.java
│ │ │ └── autoproxy
│ │ │ └── DefaultAdvisorAutoProxyCreator.java
│ │ ├── beans
│ │ │ ├── BeansException.java
│ │ │ ├── PropertyValue.java
│ │ │ ├── PropertyValues.java
│ │ │ └── factory
│ │ │ ├── Aware.java
│ │ │ ├── BeanClassLoaderAware.java
│ │ │ ├── BeanFactory.java
│ │ │ ├── BeanFactoryAware.java
│ │ │ ├── BeanNameAware.java
│ │ │ ├── ConfigurableListableBeanFactory.java
│ │ │ ├── DisposableBean.java
│ │ │ ├── FactoryBean.java
│ │ │ ├── HierarchicalBeanFactory.java
│ │ │ ├── InitializingBean.java
│ │ │ ├── ListableBeanFactory.java
│ │ │ ├── ObjectFactory.java
│ │ │ ├── PropertyPlaceholderConfigurer.java
│ │ │ ├── annotation
│ │ │ │ ├── Autowired.java
│ │ │ │ ├── AutowiredAnnotationBeanPostProcessor.java
│ │ │ │ ├── Qualifier.java
│ │ │ │ └── Value.java
│ │ │ ├── config
│ │ │ │ ├── AutowireCapableBeanFactory.java
│ │ │ │ ├── BeanDefinition.java
│ │ │ │ ├── BeanFactoryPostProcessor.java
│ │ │ │ ├── BeanPostProcessor.java
│ │ │ │ ├── BeanReference.java
│ │ │ │ ├── ConfigurableBeanFactory.java
│ │ │ │ ├── InstantiationAwareBeanPostProcessor.java
│ │ │ │ └── SingletonBeanRegistry.java
│ │ │ ├── support
│ │ │ │ ├── AbstractAutowireCapableBeanFactory.java
│ │ │ │ ├── AbstractBeanDefinitionReader.java
│ │ │ │ ├── AbstractBeanFactory.java
│ │ │ │ ├── BeanDefinitionReader.java
│ │ │ │ ├── BeanDefinitionRegistry.java
│ │ │ │ ├── CglibSubclassingInstantiationStrategy.java
│ │ │ │ ├── DefaultListableBeanFactory.java
│ │ │ │ ├── DefaultSingletonBeanRegistry.java
│ │ │ │ ├── DisposableBeanAdapter.java
│ │ │ │ ├── FactoryBeanRegistrySupport.java
│ │ │ │ ├── InstantiationStrategy.java
│ │ │ │ └── SimpleInstantiationStrategy.java
│ │ │ └── xml
│ │ │ └── XmlBeanDefinitionReader.java
│ │ ├── context
│ │ │ ├── ApplicationContext.java
│ │ │ ├── ApplicationContextAware.java
│ │ │ ├── ApplicationEvent.java
│ │ │ ├── ApplicationEventPublisher.java
│ │ │ ├── ApplicationListener.java
│ │ │ ├── ConfigurableApplicationContext.java
│ │ │ ├── annotation
│ │ │ │ ├── ClassPathBeanDefinitionScanner.java
│ │ │ │ ├── ClassPathScanningCandidateComponentProvider.java
│ │ │ │ └── Scope.java
│ │ │ ├── event
│ │ │ │ ├── AbstractApplicationEventMulticaster.java
│ │ │ │ ├── ApplicationContextEvent.java
│ │ │ │ ├── ApplicationEventMulticaster.java
│ │ │ │ ├── ContextClosedEvent.java
│ │ │ │ ├── ContextRefreshedEvent.java
│ │ │ │ └── SimpleApplicationEventMulticaster.java
│ │ │ └── support
│ │ │ ├── AbstractApplicationContext.java
│ │ │ ├── AbstractRefreshableApplicationContext.java
│ │ │ ├── AbstractXmlApplicationContext.java
│ │ │ ├── ApplicationContextAwareProcessor.java
│ │ │ ├── ClassPathXmlApplicationContext.java
│ │ │ └── ConversionServiceFactoryBean.java
│ │ ├── core
│ │ │ ├── convert
│ │ │ │ ├── ConversionService.java
│ │ │ │ ├── converter
│ │ │ │ │ ├── Converter.java
│ │ │ │ │ ├── ConverterFactory.java
│ │ │ │ │ ├── ConverterRegistry.java
│ │ │ │ │ └── GenericConverter.java
│ │ │ │ └── support
│ │ │ │ ├── DefaultConversionService.java
│ │ │ │ ├── GenericConversionService.java
│ │ │ │ └── StringToNumberConverterFactory.java
│ │ │ └── io
│ │ │ ├── ClassPathResource.java
│ │ │ ├── DefaultResourceLoader.java
│ │ │ ├── FileSystemResource.java
│ │ │ ├── Resource.java
│ │ │ ├── ResourceLoader.java
│ │ │ └── UrlResource.java
│ │ ├── stereotype
│ │ │ └── Component.java
│ │ └── util
│ │ ├── ClassUtils.java
│ │ ├── NumberUtils.java
│ │ └── StringValueResolver.java
│ └── resources
└── test
├── java
│ └── lqf
│ └── springframework
│ ├── SpringTest.java
│ ├── bean
│ │ └── Husband.java
│ └── converter
│ ├── ConvertersFactoryBean.java
│ ├── StringToIntegerConverter.java
│ └── StringToLocalDateConverter.java
└── resources
├── spring.xml
└── token.properties
设计
如果把看上去一个简单的类型转换操作抽象成框架,那么它就需要一个标准的接口,谁实现这个接口就具备类型转换的具体实现,提供类型转换的能力。那么在有了这样接口后,还需要类型转换服务的注册、工厂等内容,才可以把类型转换抽象成一个组件服务。整体设计结构如下图:

- 首先从工厂出发,需要实现一个
ConversionServiceFactoryBean来对类型转换服务进行操作。 - 而实现类型转换的服务,需要定义
Converter转换类型、ConverterRegistry注册类型转换功能,另外转换类型的操作较多,所以这里也会需要定义一个类型转换工厂
ConverterFactory各个具体的转换操作来实现这个工厂接口。
实现
定义类型转换接口
类型转换处理接口: lqf.springframework.core.convert.converter.Converter
类型转换工厂: lqf.springframework.core.convert.converter.ConverterFactory
类型转换注册接口: lqf.springframework.core.convert.converter.ConverterRegistry
- Converter、ConverterFactory、ConverterRegistry,都是用于自定义类型转换操作的相关接口,后续所有的实现都需要围绕这些接口来实现,具体的代码功能可以进行调试验证。
实现类型转换服务
类型转换服务: lqf.springframework.core.convert.support.DefaultConversionService
- DefaultConversionService 是继承 GenericConversionService 的实现类,而 GenericConversionService 实现了
ConversionService,ConverterRegistry 两个接口,用于 canConvert 判断和转换接口 convert 操作。
创建类型转换工厂
类型转换工厂: lqf.springframework.context.support.ConversionServiceFactoryBean
- 有了 FactoryBean 的实现就可以完成工程对象的操作,可以提供出转换对象的服务 GenericConversionService, 另外在
afterPropertiesSet 中调用了注册转换操作的类。最终这个类会被配置到 spring.xml 中在启动的过程加载。
类型转换服务使用
类型转换服务使用: lqf.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
- 在 AbstractAutowireCapableBeanFactory#applyPropertyValues 填充属性的操作中,具体使用了类型转换的功能。
- 在 AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues 也有同样的属性类型转换操作。
总结
-
此处实现的类型转换操作如果只是功能性的开发,就像自己承接的需求那样,可能只是简单的if判断就搞定了,但是放在一个成熟的框架中要考虑的是可复用性、
可拓展性,所以会看到接口的定义、工厂的使用等等设计模式在这里面体现。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 iAuzre
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果
音乐天地