Spring底层架构源码剖析(三)

[复制链接]
发表于 2026-1-18 06:33:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目次
ApplicationContext
AnnotationConfigApplicationContext
ClassPathXmlApplicationContext 
范例转换 
PropertyEditor
ConversionService
BeanPostProcessor
FactoryBean 
MetadataReader、ClassMetadata、 AnnotationMetadata
ExcludeFilter,IncludeFilter

有关spring的前置知识,可以观看我的上一篇文章spring底层架构源码剖析(二)
ApplicationContext

接上一篇文章,再将到BeanFactory后不得不提到ApplicationContext了,ApplicationContext着实是继承了BeanFactory的,但是ApplicationContext提供了比BeanFactory更多的功能,此中ApplicationContext两个比力告急的实现类:
   1. AnnotationConfigApplicationContext
  2. ClassPathXmlApplicationContext
  AnnotationConfigApplicationContext

在idea的继承图如下,可以发现AnnotationConfigApplicationContext实现了许多的接口

   1. ConfigurableApplicationContext:继承了ApplicationContext接口,增长了,添加变乱监听 器、添加BeanFactoryPostProcessor、设置Environment,获取 ConfigurableListableBeanFactory等功能
  
  2. AbstractApplicationContext:实现了ConfigurableApplicationContext接口
  
  3. GenericApplicationContext:继承了AbstractApplicationContext,实现了 BeanDefinitionRegistry接口,拥有了全部ApplicationContext的功能,而且可以注册 BeanDefinition,注意这个类中有一个属性(DefaultListableBeanFactory beanFactory)
  
  4. AnnotationConfigRegistry:可以单独注册某个为类为BeanDefinition(可以处置惩罚该类上的 **@Configuration注解**,已经可以处置惩罚**@Bean注解**),同时可以扫描
  
  5. AnnotationConfigApplicationContext:继承了GenericApplicationContext,实现了 AnnotationConfigRegistry接口,拥有了以上全部的功能  
  ClassPathXmlApplicationContext 

同样,在idea的继承图如下,可以发现ClassPathXmlApplicationContext实现了许多的接口

范例转换 

在spring的源码中有许多范例转换的工具类,比方:PropertyEditor,ConversionService,TypeConverter等,他们可以将我们写的String转换为spring必要加载的类对象
PropertyEditor

  1. public class StringToUserPropertyEditor extends PropertyEditorSupport implements 
  2. PropertyEditor { 
  3.   @Override 
  4.   public void setAsText(String text) throws IllegalArgumentException { 
  5.     User user = new User(); 
  6.     user.setName(text); 
  7.     this.setValue(user); 
  8.   } 
  9. } 
复制代码
怎样向Spring中注册PropertyEditor:
  1. @Bean 
  2. public CustomEditorConfigurer customEditorConfigurer() { 
  3.   CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer(); 
  4.   Map<Class<?>, Class<? extends PropertyEditor>> propertyEditorMap = new HashMap<>(); 
  5.      
  6.     // 表示StringToUserPropertyEditor可以将String转化成User类型,在Spring源码中,如果发现当前
  7. 对象是String,而需要的类型是User,就会使用该PropertyEditor来做类型转化 
  8.   propertyEditorMap.put(User.class, StringToUserPropertyEditor.class); 
  9.   customEditorConfigurer.setCustomEditors(propertyEditorMap); 
  10.   return customEditorConfigurer; 
  11. } 
复制代码
ConversionService

ConversionService是比PropertyEditor更为强盛的范例转换类
  1. public class StringToUserConverter implements ConditionalGenericConverter { 
  2.   @Override 
  3.   public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { 
  4.     return sourceType.getType().equals(String.class) && 
  5. targetType.getType().equals(User.class); 
  6.   } 
  7.   @Override 
  8.   public Set<ConvertiblePair> getConvertibleTypes() { 
  9.     return Collections.singleton(new ConvertiblePair(String.class, User.class)); 
  10.   } 
  11.   @Override 
  12.   public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor 
  13. targetType) { 
  14.     User user = new User(); 
  15.     user.setName((String)source); 
  16.     return user; 
  17.   } 
  18. } 
复制代码
怎样向Spring中注册ConversionService:
  1. @Bean 
  2. public ConversionServiceFactoryBean conversionService() { 
  3.   ConversionServiceFactoryBean conversionServiceFactoryBean = new 
  4. ConversionServiceFactoryBean(); 
  5.   conversionServiceFactoryBean.setConverters(Collections.singleton(new 
  6. StringToUserConverter())); 
  7.   return conversionServiceFactoryBean; 
  8. } 
复制代码
BeanPostProcessor

BeanPostProcess表现Bena的后置处置惩罚器,我们可以界说一个或多个BeanPostProcessor,好比通 过以下代码界说一个BeanPostProcessor:
  1. @Component 
  2. public class LcyyBeanPostProcessor implements BeanPostProcessor { 
  3.   @Override 
  4.   public Object postProcessBeforeInitialization(Object bean, String beanName) throws 
  5. BeansException { 
  6.     if ("userService".equals(beanName)) { 
  7.       System.out.println("Bean的初始化前"); 
  8.     } 
  9.     return bean; 
  10.   } 
  11.   @Override 
  12.   public Object postProcessAfterInitialization(Object bean, String beanName) throws 
  13. BeansException { 
  14.     if ("userService".equals(beanName)) { 
  15.       System.out.println("Bean的初始化后"); 
  16.     } 
  17.     return bean; 
  18.   } 
  19. } 
复制代码
一个BeanPostProcessor可以在恣意一个Bean的初始化之前以及初始化之后去额外的做一些用户自 界说的逻辑,固然,我们可以通过判断beanName来举行针对性处置惩罚(针对某个Bean,或某部门 Bean)。 因此可以通过界说BeanPostProcessor来干涉Spring创建Bean的过程。
FactoryBean 

FactoryBean 着实是一个比力特殊的Bean,可以通过BeanPostPorcessor来干涉Spring创建Bean的过程,但是如果我们想一个 Bean完完全全由我们来创造,也是可以的,好比通FactoryBean
  1. @Component 
  2. public class LcyyFactoryBean implements FactoryBean { 
  3.   @Override 
  4.   public Object getObject() throws Exception { 
  5.     UserService userService = new UserService(); 
  6.     return userService; 
  7.   } 
  8.   @Override 
  9.   public Class<?> getObjectType() { 
  10.     return UserService.class; 
  11.   } 
  12. } 
复制代码
通过上面这段代码,我们本身创造了一个UserService对象,而且它将成为Bean。但是通过这种方式 创造出来的UserService的Bean,只会颠末初始化后,其他Spring的生命周期步调是不会颠末的,好比依赖注入。
MetadataReader、ClassMetadata、 AnnotationMetadata

在Spring中必要去剖析类的信息,好比类名、类中的方法、类上的注解,这些都可以称之为类的元数 据,以是Spring中对类的元数据做了抽象,并提供了一些工具类。MetadataReader表现类的元数据读取器,默认实现类为SimpleMetadataReader
  1. public class Test { 
  2.   public static void main(String[] args) throws IOException { 
  3.     SimpleMetadataReaderFactory simpleMetadataReaderFactory = new 
  4. SimpleMetadataReaderFactory(); 
  5.      
  6.         // 构造一个MetadataReader 
  7.         MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.lcyy.service.UserService"); 
  8.      
  9.         // 得到一个ClassMetadata,并获取了类名 
  10.         ClassMetadata classMetadata = metadataReader.getClassMetadata(); 
  11.    
  12.         System.out.println(classMetadata.getClassName()); 
  13.          
  14.         // 获取一个AnnotationMetadata,并获取类上的注解信息 
  15.         AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); 
  16.     for (String annotationType : annotationMetadata.getAnnotationTypes()) { 
  17.       System.out.println(annotationType); 
  18.     } 
  19.   } 
  20. } 
复制代码
ExcludeFilter,IncludeFilter

这两个Filter是Spring扫描过程中用来过滤的。ExcludeFilter表现扫除过滤器,IncludeFilter表现包 含过滤器。 好比以下设置,表现扫描com.lcyy这个包下面的全部类,但是扫除UserService类,也就是就算它上面有@Component注解也不会成为Bean。
  1. @ComponentScan(value = "com.lcyy", 
  2.     excludeFilters = {@ComponentScan.Filter( 
  3.               type = FilterType.ASSIGNABLE_TYPE,  
  4.               classes = UserService.class)}.) 
  5. public class AppConfig { 
  6. }
复制代码
再好比以下设置,就算UserService类上没有@Component注解,它也会被扫描成为一个Bean。
  1. @ComponentScan(value = "com.lcyy", 
  2.     includeFilters = {@ComponentScan.Filter( 
  3.               type = FilterType.ASSIGNABLE_TYPE,  
  4.               classes = UserService.class)}) 
  5. public class AppConfig { 
  6. }
复制代码
  FilterType分为:
  
  1. ANNOTATION:表现是否包罗某个注解
  2. ASSIGNABLE_TYPE:表现是否是某个类
  3. ASPECTJ:表现否是符合某个Aspectj表达式
  4. REGEX:表现是否符合某个正则表达式
  5. CUSTOM:自界说
  
  在Spring的扫描逻辑中,默认会添加一个AnnotationTypeFilter给includeFilters,表现默认环境下 Spring扫描过程中会以为类上有@Component注解的就是Bean。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表