Skip to content

wangchirl/spring-extension-core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 

Repository files navigation

扩展

1、自定义 beanName

 * 1自定义 beanName 生成器
 *
 * @see org.springframework.beans.factory.support.BeanNameGenerator#generateBeanName(BeanDefinition, BeanDefinitionRegistry)
 * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator
 * @see org.springframework.context.annotation.AnnotationBeanNameGenerator
 * @see org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator

2、自定义 xml 标签

  * 1BeanDefinition 解析器
  * @see org.springframework.beans.factory.xml.BeanDefinitionParser
  * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser
  * @see org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser
  * @see org.apache.dubbo.config.spring.schema.AnnotationBeanDefinitionParser
  * @see org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser
  *
  * 案例:
  *   ① Dubbo 自定义 Xml 标签解析器
  *      @see org.apache.dubbo.config.spring.schema.DubboBeanDefinitionParser
  *   ② Mybatis 自定义 Xml 标签解析器
  *      @see org.mybatis.spring.config.MapperScannerBeanDefinitionParser
  *
  * 2、.xsd 文件
  *
  * 3META-INF/spring.schemas
  *
  * 4META-INF/spring.handlers
  *      @see org.springframework.beans.factory.xml.NamespaceHandler#init()
  *      @see org.springframework.beans.factory.xml.NamespaceHandlerSupport#init()

3、自定义 属性编辑器 xml版

 * 1属性编辑器
 * @see java.beans.PropertyEditorSupport#setAsText(String)
 * @see org.springframework.beans.PropertyEditorRegistrar#registerCustomEditors(PropertyEditorRegistry)
 *
 * 2注入 IOC 容器
 * @see org.springframework.beans.factory.config.CustomEditorConfigurer#setPropertyEditorRegistrars(PropertyEditorRegistrar[])
 * @see org.springframework.beans.factory.config.CustomEditorConfigurer#setCustomEditors(Map)

4、自定义 属性编辑器 注解版

 * 1属性编辑器
 * @see java.beans.PropertyEditorSupport#setAsText(String)
 * @see org.springframework.beans.PropertyEditorRegistrar#registerCustomEditors(PropertyEditorRegistry)
 *
 * 2注入 IOC 容器
 * @see org.springframework.beans.factory.config.CustomEditorConfigurer#setPropertyEditorRegistrars(PropertyEditorRegistrar[])
 * @see org.springframework.beans.factory.config.CustomEditorConfigurer#setCustomEditors(Map)
 *
 * 3@Configuration - 配置类
 *
 * 4@PropertySource - 读取配置文件
 *
 * 5@Bean - 注入对象到 IOC 容器

5、BFPP

 * 1BFPP 可以对工厂中的 BeanDefinition 进行修改操作
 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)

6、BDRPP

 * 1BDRPP 可以往工厂中注入新的 BD 对象
 * 2BFPP 可以修改工厂中的 BD
 * @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)

7、BDRPP 执行顺序

 * 1BDRPP 有执行顺序
 *  ① 首先执行用户通过编程方式手动注册的 BDRPP 的方法
 *  ② 再执行实现了 PriorityOrdered 接口的排序后的 BDRPP 的方法
 *  ③ 然后执行实现了 Ordered 接口的排序后的 BDRPP 的方法
 *  ④ 最后执行没有实现上面2个接口的 BDRPP 的方法
 *  ⑤ 执行 BFPP 的方法
 *  >>> 按序执行的理由BDRPP 可以注册 BDRPP 到工厂中
 * @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
 *
 * 2BFPP 有执行顺序
 *  ① 首先执行实现了 PriorityOrdered 接口的排序后的 BFPP 的方法
 *  ② 再执行实现了 Ordered 接口的排序后的 BFPP 的方法
 *  ③ 最后执行没有实现上面2个接口的 BFPP 的方法
 *  >>> 处理 BeanDefinition 的顺序
 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)

8、BPP 执行顺序

 * @see org.springframework.beans.factory.config.BeanPostProcessor -> bean 初始化前后干点事
 * 1注册 BPP 到工厂中的 beanPostProcessors 集合中
 *   ① 首先将实现了 PriorityOrdered 接口的 BPP 实例化并 add  beanPostProcessors 集合中
 *   ② 再将实现了 Ordered 接口的 BPP 实例化并 add  beanPostProcessors 集合中
 *   ③ 然后将未实现上面2个接口的 BPP 实例化并 add  beanPostProcessors 集合中
 *   ④ 最后将 Spring 内部的 BPP 实例化并 add  beanPostProcessors 集合中
 *
 * 2BeanPostProcessor 子接口及其作用
 * @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor -> bean实例化前后干点事
 * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor -> bean 循环依赖问题
 * @see org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor -> 允许在实例化 bean 后修改 BeanDefinition
 * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor -> bean 对象销毁前干点事

9、自定义类型转换器

 *  1类型转换器
 *  Converter -> 1 - 1 转换
 *  ConverterFactory -> 1 - N 转换
 *  GenericConverter -> N - N 转换
 * @see org.springframework.core.convert.converter.Converter#convert(Object)
 * @see org.springframework.core.convert.converter.ConverterFactory#getConverter(Class)
 * @see org.springframework.core.convert.converter.GenericConverter#convert(Object, TypeDescriptor, TypeDescriptor)
 *
 * 2Java 自带的属性编辑器上面的 Spring 提供的功能更强大
 * @see java.beans.PropertyEditorSupport#setAsText(String)
 * @see com.shadow.extension03_editor_xml
 * @see com.shadow.extension04_editor_annotation

10、依赖bean

 * 1依赖对象
 * @see org.springframework.context.annotation.DependsOn
 *
 * 实例化某个对象时需要另外一个类型的对象先创建
 * 比如实例化 JdbcTemplate 对象时需要先创建好 DataSource 对象
 * @see org.springframework.jdbc.core.JdbcTemplate
 * @see javax.sql.DataSource

11、创建 bean 方式

 * 1允许提前创建 bean 对象
 *  ① InstantiationAwareBeanPostProcessor -> BPP 的子接口
 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(Class, String)
 *  ② Supplier
 * @see Supplier
 * @see org.springframework.beans.factory.support.AbstractBeanDefinition#setInstanceSupplier(Supplier)
 *  ③ FactoryMethod or StaticFactoryMethod 工厂方法或静态工厂方法 factory-methodfactory-bean

12、lookup、replace

 *  1lookup-method
 *      Spring 中默认的对象是单例的Spring 会在一级缓存中持有该对象方便下次直接获取
 *      那么如果是原型作用域的话会创建一个新的对象
 *
 *      如果想在一个单例 bean 中引用一个原型的 bean 的话怎么办呢?
 *      此时就需要引用 lookup-method 标签来解决此问题
 *      @see org.springframework.beans.factory.annotation.Lookup
 *
 *      通过拦截器的方式每次需要的时候都去创建新的对象而不是把原型对象缓存起来
 *      <lookup-method></lookup-method> xml 标签
 *
 *  2replace-method
 *      @see org.springframework.beans.factory.support.MethodReplacer
 *      <replace-method></replace-method>

13、属性填充

 *  1属性填充
 *  <property></property>
 *  <array></array> -> 数组对象
 *  <list></list>   -> list 集合对象
 *  <set></set>     -> set 集合对象
 *  <map></map>     -> map 集合对象
 *  <props></props> -> Properties 对象

14、循环依赖

 *  1循环依赖
 *      Spring 通过三级缓存来解决循环依赖问题:
 *      其实解决循环依赖问题是要二级缓存就可以了为什么 Spring 要使用三级缓存呢?
 *  @see org.springframework.beans.factory.support.DefaultListableBeanFactory
 *  ① singletonObjects      -> 一级缓存
 *  ② earlySingletonObjects -> 二级缓存
 *  ③ singletonFactories    -> 三级缓存
 *
 *  提前暴露创建后但未完全创建完成的 bean 对象
 *  @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference(Object, String)
 *
 *  使用三级缓存的目的是为了能够对 bean 进行代理
 *  @see org.springframework.beans.factory.ObjectFactory#getObject
 *
 *  对比 FactoryBean
 *  @see org.springframework.beans.factory.FactoryBean#getObject
 *
 *  2可以关闭循环依赖
 * @see AnnotationConfigApplicationContext#setAllowCircularReferences(boolean)
 * @see ClassPathXmlApplicationContext#setAllowCircularReferences(boolean)
 * @see org.springframework.context.support.AbstractXmlApplicationContext#setAllowCircularReferences(boolean)

15、bean 生命周期

 * 1bean 的生命周期:
 *  ① bean 的实例化
 *  ② bean 的属性填充
 *  ③ *Aware 接口方法设置属性
 *  ④ BPP  Before 回调方法
 *  ⑤ bean 的初始化方法
 *      @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
 *      自定义 init-method 初始化方法
 *  ⑥ BPP  After 回调方法
 *  ⑦ bean 的销毁
 *      @see org.springframework.beans.factory.DisposableBean#destroy
 *      自定义 destroy-method 销毁方法
 *
 *  2初始化注解插曲
 *  @see javax.annotation.PostConstruct
 *  @see javax.annotation.PreDestroy
 *      处理类 :
 *      @see org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor

16、FactoryBean

 *  1BeanFactory bean 工厂 IOC 容器
 *      ① 存放 BeanDefinition 的容器 beanDefinitionMap
 *      ② 存放单例的容器 singletonObjects
 *      ③ 创建管理 bean 的容器
 *
 *  2FactoryBean 工厂 bean
 *      ① FactoryBean 对象也有 BeanFactory 工厂来管理
 *      ② FactoryBean 可以通过其 getObject 方法生产对象
 *      ③ 直接根据 beanName 获取的对象是其 getObject 方法生产的对象
 *      ④ 如果想获取 FactoryBean 对象的话需要在 beanName 前拼接上取地址符 &
 *      ⑤ FactoryBean 通常来实现对象代理
 *  @see org.mybatis.spring.mapper.MapperFactoryBean     -> Mybatis
 *  @see org.apache.dubbo.config.spring.ReferenceBean    -> Dubbo

17、动态代理

 *  1JDK 动态代理反射)
 *      -> 代理的类一定要是实现接口的类
 * @see java.lang.reflect.Proxy
 * @see java.lang.reflect.Proxy.ProxyClassFactory#apply(ClassLoader, Class[])
 * @see java.lang.reflect.InvocationHandler#invoke(Object, Method, Object[])
 *
 *  2CGLIB 动态代理ASM 字节码操作技术)
 *      -> 代理的类无需实现任何接口
 * @see org.springframework.cglib.proxy.Enhancer#setSuperclass(Class)
 * @see org.springframework.cglib.proxy.Enhancer#setCallback(Callback)
 * @see org.springframework.cglib.proxy.Enhancer#create()
 * @see org.springframework.cglib.proxy.MethodInterceptor#intercept(Object, Method, Object[], MethodProxy)
 *
 *  3生产的动态代理类保存到本地
 *      -> JDK 动态代理
 *          System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true")
 *      -> CGLIB 动态代理
 *          System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, System.getProperty("user.dir"))

18、AOP

 *  1AOP 切面编程 -> OOP 补充
 *      ① 切面 Aspect -> 自定义
 *      ② 连接点 JoinPoint -> Spring 中的连接点泛指方法
 *      ③ 通知 Advise
 *          @see org.springframework.aop.aspectj.AspectJMethodBeforeAdvice -> 前置通知
 *          @see org.springframework.aop.aspectj.AspectJAfterAdvice -> 后置通知
 *          @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice -> 返回通知
 *          @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice -> 异常通知
 *          @see org.springframework.aop.aspectj.AspectJAroundAdvice -> 环绕通知
 *      
 *      通知注解:
 *          @see org.aspectj.lang.annotation.Before
 *          @see org.aspectj.lang.annotation.After
 *          @see org.aspectj.lang.annotation.AfterReturning
 *          @see org.aspectj.lang.annotation.AfterThrowing
 *          @see org.aspectj.lang.annotation.Around
 *      
 *      ④ 切点 Pointcut
 *          @see org.springframework.aop.Pointcut
 *          @see org.springframework.aop.aspectj.AspectJExpressionPointcut
 * 
 *      ⑤ 通知器 Advisor  Advise  Pointcut 的包装
 *          @see org.springframework.aop.aspectj.AspectJPointcutAdvisor
 *          @see org.springframework.aop.aspectj.AspectJPointcutAdvisor#advice
 *          @see org.springframework.aop.aspectj.AspectJPointcutAdvisor#pointcut
 *          
 *          在执行过程中通知器其实是在一个链中的其链开始的是 ExposeInvocationInterceptor
 *          @see org.springframework.aop.interceptor.ExposeInvocationInterceptor
 *          
 *  2通知实现的分类:
 *      @see org.aopalliance.intercept.MethodInterceptor
 *      @see org.springframework.aop.aspectj.AspectJAfterAdvice
 *      @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
 *      @see org.springframework.aop.aspectj.AspectJAroundAdvice
 *          
 *  3Xml 方式的通知器在执行过程中与在 Xml 配置的先后顺序有关取的是配置顺序的下标顺序Before - AroundAfter - Around

19、Spring 事务

 *  1事务隔离级别
 *  @see org.springframework.transaction.annotation.Isolation
 *      ① DEFAULT - 与数据库事务隔离级别保存一致
 *      ② READ_UNCOMMITTED - 读未提交
 *      ③ READ_COMMITTED - 读已提交
 *      ④ REPEATABLE_READ - 可重复读
 *      ⑤ SERIALIZABLE - 可串行化
 *
 *  2事务传播机制
 *  @see org.springframework.transaction.annotation.Propagation
 *    支持当前事务的
 *      ① REQUIRED - 使用当前事务没有就创建
 *      ② SUPPORTS - 当前有事务就使用当前事务当前没有事务就不用事务
 *      ③ MANDATORY - 使用当前事务没有就报错
 *    不支持当前事务的
 *      ① REQUIRES_NEW - 当前存在事务就挂起当前事务重新创建一个新事务
 *      ② NOT_SUPPORTED - 不需要事务当前存在事务就挂起事务
 *      ③ NEVER - 不需要事务存在事务就报错
 *    内嵌事务
 *      ① NESTED - 当前存在事务创建保存点新建一个事务
 *
 *  3声明式事务注解
 *  @see org.springframework.transaction.annotation.Transactional
 *
 *  4事务管理器
 *  @see org.springframework.transaction.PlatformTransactionManager
 *  @see org.springframework.jdbc.datasource.DataSourceTransactionManager

20、Import 的使用

 *  1@Import 注解注册类到 IOC 容器
 *    ① 普通的 class容器会自动注册这个类id 默认全类名
 *    ② ImportSelector 接口注册一批 class
 *      @see org.springframework.context.annotation.ImportSelector#selectImports(AnnotationMetadata)
 *    ③ ImportBeanDefinitionRegistrar 一般结合扫描注解使用
 *      @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry)
 *      接口方法参数 AnnotationMetadata,它可以获取当前类@Import标记的注解消息它使用标准的反射来获取指定类的内部注解消息
 *      @see AnnotationMetadata#getAnnotationTypes()
 *      案例Mybatis mapper 扫描
 *      @see org.mybatis.spring.annotation.MapperScannerRegistrar
 *
 *   特别说明ImportSelectorImportBeanDefinitionRegistrar 实现类均可实现以下接口作为扩展需要注入需要的属性
 *      @see org.springframework.context.EnvironmentAware#setEnvironment(Environment)
 *      @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(BeanFactory)
 *      @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(ClassLoader)
 *      @see org.springframework.context.ResourceLoaderAware#setResourceLoader(ResourceLoader)

21、自定义扫描器

 *  1自定义注解扫描技术参考 Dubbo  ServiceBean 注解类注册
 *      ① @Shadow -> @Component
 *      ② @ShadowScan -> @ComponentScan
 *      ③ ShadowBeanFactoryPostProcessor -> org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor
 *          @see org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor
 *      ④ CustomerScanImportBeanDefinitionRegistrar -> org.apache.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar
 *          @see org.apache.dubbo.config.spring.context.annotation.DubboComponentScanRegistrar
 *      ⑤ 自定义扫描器  ShadowBeanScannner

22、SPI 机制

 *  1JAVA SPI 机制:
 *      ① 接口
 *      ② 实现类
 *      ③ META-INF/services/接口全类名文件
 *      ④ 接口全类名文件中写入具体的实现类多个实现可换行处理
 *   原理:
 *      @see ServiceLoader#load(Class)
 *
 *  2Spring SPI 机制:
 *      ① 接口
 *      ② 接口实现类
 *      ③ META-INF/spring.factories 文件
 *      ④ spring.factories 文件中写入 接口全类名=接口实现类全类名多个以英文逗号隔开
 *
 *    原理:
 *      @see SpringFactoriesLoader#loadFactories(Class, ClassLoader)

23、按需注入 bean

 *  1条件匹配
 *      @see org.springframework.context.annotation.Condition#matches(ConditionContext, AnnotatedTypeMetadata)
 *      @see org.springframework.context.annotation.Conditional
 *
 *     常用注解:
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnBean
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnClass
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnResource
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
 *         @see org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication
 *
 *  2自定义条件
 *      ① 实现接口 Condition  matches 方法
 *      @see org.springframework.context.annotation.Condition#matches(ConditionContext, AnnotatedTypeMetadata)
 *      ② 使用注解 @Conditional(value = {xxxCondition.class})
 *      @see org.springframework.context.annotation.Conditional#value()

About

Spring 源码 + 扩展 + 练习

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages