json解析错误_springboot源码架构解析postProcessor

说在前面

前期回顾

sharding-jdbc源码解析 更新完毕

spring源码解析 更新完毕

spring-mvc源码解析 更新完毕

spring-tx源码解析 更新完毕

spring-boot源码解析 更新完毕

rocketmq源码解析 更新完毕

dubbbo源码解析 更新完毕

netty源码解析 更新完毕

spring源码架构更新完毕

spring-mvc源码架构更新完毕

springboot源码架构更新中

github https://github.com/tianheframe

sharding-jdbc源码解析 更新完毕

rocketmq源码解析 更新完毕

seata 源码解析 更新完毕

dubbo 源码解析 更新完毕

netty 源码解析 更新完毕

源码解析

b33dde5c6205df3c8ed0bada305f304c.png

org.springframework.boot.env.EnvironmentPostProcessor 允许在刷新应用程序上下文之前定制应用程序环境。EnvironmentPostProcessor实现必须在META-INF/spring中注册。使用该类的完全限定名作为键。我们鼓励EnvironmentPostProcessor处理器检测Spring的有序接口是否已经实现,或者是否存在@Order注释,并在调用之前对实例进行相应的排序。

void postProcessEnvironment(ConfigurableEnvironment environment,      SpringApplication application);

对environment进行处理

org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor 一个从spring.application解析JSON的环境后处理器。将其作为映射属性源添加到环境中。新属性的添加具有比系统属性更高的优先级。

private static final String SERVLET_ENVIRONMENT_CLASS = "org.springframework.web."      + "context.support.StandardServletEnvironment";

服务环境类名

@Override  public void postProcessEnvironment(ConfigurableEnvironment environment,      SpringApplication application) {    String json = environment.resolvePlaceholders(        "${spring.application.json:${SPRING_APPLICATION_JSON:}}");    if (StringUtils.hasText(json)) {      processJson(environment, json);    }  }

org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor#processJson

private void processJson(ConfigurableEnvironment environment, String json) {    try {      JsonParser parser = JsonParserFactory.getJsonParser();      Mapmap = parser.parseMap(json);      if (!map.isEmpty()) {        addJsonPropertySource(environment,            new MapPropertySource("spring.application.json", flatten(map)));      }    }    catch (Exception ex) {      logger.warn("Cannot parse JSON for spring.application.json: " + json, ex);    }  }

获得json解析器处理json配置文件

org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessorRegistrar importbeandefinition registry用于将外部应用程序属性绑定到ConfigurationProperties bean。

  @Override  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,      BeanDefinitionRegistry registry) {//    判断BeanFactory中是否包含ConfigurationPropertiesBindingPostProcessor BeanDefinition    if (!registry.containsBeanDefinition(BINDER_BEAN_NAME)) {//      创建ConfigurationBeanFactoryMetaData BeanDefinition      BeanDefinitionBuilder meta = BeanDefinitionBuilder          .genericBeanDefinition(ConfigurationBeanFactoryMetaData.class);//      创建ConfigurationPropertiesBindingPostProcessor BeanDefinition      BeanDefinitionBuilder bean = BeanDefinitionBuilder.genericBeanDefinition(          ConfigurationPropertiesBindingPostProcessor.class);      bean.addPropertyReference("beanMetaDataStore", METADATA_BEAN_NAME);      registry.registerBeanDefinition(BINDER_BEAN_NAME, bean.getBeanDefinition());      registry.registerBeanDefinition(METADATA_BEAN_NAME, meta.getBeanDefinition());    }  }

注册BeanDefinition

@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ConfigurationProperties {

外部配置的注释。如果您想绑定和验证一些外部属性(例如来自. Properties文件),请将其添加到@Configuration类中的类定义或@Bean方法中。注意,与@Value相反,SpEL表达式不计算值,因为属性值是外部化的。

@AliasFor("prefix")  String value() default "";

绑定到此对象的有效属性的名称前缀。前缀的同义词()。

@AliasFor("value")  String prefix() default "";

绑定到此对象的有效属性的名称前缀。价值的同义词()。

boolean ignoreInvalidFields() default false;

标志,指示绑定到此对象时应忽略无效字段。根据使用的绑定器,Invalid表示无效,通常这表示类型错误的字段(或者不能强制转换为正确的类型)。

boolean ignoreNestedProperties() default false;

标记,以指示在绑定到此对象字段时应忽略其名称中有句点的字段。

  boolean ignoreUnknownFields() default true;

标志,指示绑定到此对象时应忽略未知字段。未知字段可能是属性错误的标志。

  @Deprecated  boolean exceptionIfInvalid() default true;

标志,指示如果验证器可用,则应引发异常,该类将使用@Validated进行注释,验证失败。如果将其设置为false,验证错误将被吞噬。它们将被记录下来,但不会传播给调用者。

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(EnableConfigurationPropertiesImportSelector.class)public @interface EnableConfigurationProperties {

启用对ConfigurationProperties注释bean的支持。ConfigurationProperties bean可以用标准的方式注册(例如使用@Bean方法),或者,为了方便起见,可以直接在这个注释上指定。

Class>[] value() default {};

用Spring快速注册带注释bean的ConfigurationProperties的方便方法。不管这个值是多少,标准Spring bean也将被扫描。

这两个注解配合使用

org.springframework.boot.context.embedded.WebApplicationContextServletContextAwareProcessor servletcontext - wareprocessor的变体,用于ConfigurableWebApplicationContext。可以在初始化ServletContext或ServletConfig之前注册处理器时使用。

  private final ConfigurableWebApplicationContext webApplicationContext;

webApplicationContext

@Override  protected ServletContext getServletContext() {    ServletContext servletContext = this.webApplicationContext.getServletContext();    return (servletContext != null) ? servletContext : super.getServletContext();  }  @Override  protected ServletConfig getServletConfig() {    ServletConfig servletConfig = this.webApplicationContext.getServletConfig();    return (servletConfig != null) ? servletConfig : super.getServletConfig();  }

获得servletContext、servletConfig

org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor 配置文件通过processor进行绑定,实现org.springframework.beans.factory.config.BeanPostProcessor、org.springframework.beans.factory.BeanFactoryAware、org.springframework.context.ApplicationContextAware、org.springframework.beans.factory.InitializingBean、org.springframework.beans.factory.DisposableBean接口。

  private Validator validator;

属性验证器

  private ConversionService conversionService;

conversionService

  private BeanFactory beanFactory;

beanFactory

  private ApplicationContext applicationContext;

applicationContext

  private List, ?>> converters = Collections.emptyList();

converters

@Autowired(required = false)  @ConfigurationPropertiesBinding  public void setConverters(List> converters) {    this.converters = converters;  }

在转换用于绑定的属性时使用的自定义转换器列表(除了默认值之外)。

@Qualifier@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ConfigurationPropertiesBinding {}

配置ConfigurationProperties绑定(例如转换器)所需的bean的限定符。

@Override  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {    this.beanFactory = beanFactory;  }

重写org.springframework.beans.factory.BeanFactoryAware#setBeanFactory方法,设置beanFactory

@Override  public void setApplicationContext(ApplicationContext applicationContext) {    this.applicationContext = applicationContext;  }

重写org.springframework.context.ApplicationContextAware#setApplicationContext方法,设置applicationContext

@Override  public void afterPropertiesSet() throws Exception {    if (this.propertySources == null) {      this.propertySources = deducePropertySources();    }    if (this.validator == null) {      this.validator = getOptionalBean(VALIDATOR_BEAN_NAME, Validator.class);    }    if (this.conversionService == null) {      this.conversionService = getOptionalBean(          ConfigurableApplicationContext.CONVERSION_SERVICE_BEAN_NAME,          ConversionService.class);    }  }

重写org.springframework.beans.factory.InitializingBean#afterPropertiesSet方法,设置validator、conversionService

@Override  public void onApplicationEvent(ContextRefreshedEvent event) {    freeLocalValidator();  }

释放Validator,org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor#freeLocalValidator

private void freeLocalValidator() {    try {      Validator validator = this.localValidator;      this.localValidator = null;      if (validator != null) {        ((DisposableBean) validator).destroy();      }    }    catch (Exception ex) {      throw new IllegalStateException(ex);    }  }

调用validator实现的org.springframework.beans.factory.DisposableBean接口的destroy方法。

@Override  public Object postProcessBeforeInitialization(Object bean, String beanName)      throws BeansException {    ConfigurationProperties annotation = AnnotationUtils        .findAnnotation(bean.getClass(), ConfigurationProperties.class);    if (annotation != null) {      postProcessBeforeInitialization(bean, beanName, annotation);    }    annotation = this.beans.findFactoryAnnotation(beanName,        ConfigurationProperties.class);    if (annotation != null) {      postProcessBeforeInitialization(bean, beanName, annotation);    }    return bean;  }

重写org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization方法,查询类、类的工厂方法上的ConfigurationProperties注解,在bean初始化之前做属性处理,org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String, org.springframework.boot.context.properties.ConfigurationProperties)

private void postProcessBeforeInitialization(Object bean, String beanName,      ConfigurationProperties annotation) {    Object target = bean;    PropertiesConfigurationFactory factory = new PropertiesConfigurationFactory(        target);    factory.setPropertySources(this.propertySources);//    设置applicationContext    factory.setApplicationContext(this.applicationContext);//    设置validator    factory.setValidator(determineValidator(bean));    // If no explicit conversion service is provided we add one so that (at least) 如果没有提供显式转换服务,则添加一个,以便(至少)    // comma-separated arrays of convertibles can be bound automatically 可自动绑定以逗号分隔的可转债阵列//    设置conversionService    factory.setConversionService((this.conversionService != null)        ? this.conversionService : getDefaultConversionService());    if (annotation != null) {      factory.setIgnoreInvalidFields(annotation.ignoreInvalidFields());      factory.setIgnoreUnknownFields(annotation.ignoreUnknownFields());      factory.setExceptionIfInvalid(annotation.exceptionIfInvalid());      factory.setIgnoreNestedProperties(annotation.ignoreNestedProperties());      if (StringUtils.hasLength(annotation.prefix())) {        factory.setTargetName(annotation.prefix());      }    }    try {//      绑定属性      factory.bindPropertiesToTarget();    }    catch (Exception ex) {      String targetClass = ClassUtils.getShortName(target.getClass());      throw new BeanCreationException(beanName, "Could not bind properties to "          + targetClass + " (" + getAnnotationDetails(annotation) + ")", ex);    }  }
@Override  public Object postProcessAfterInitialization(Object bean, String beanName)      throws BeansException {    return bean;  }

重写org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization方法,bean初始化后的方法不做处理

org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor#getDefaultConversionService

private ConversionService getDefaultConversionService() {    if (this.defaultConversionService == null) {      DefaultConversionService conversionService = new DefaultConversionService();      this.applicationContext.getAutowireCapableBeanFactory().autowireBean(this);      for (Converter, ?> converter : this.converters) {        conversionService.addConverter(converter);      }      for (GenericConverter genericConverter : this.genericConverters) {        conversionService.addConverter(genericConverter);      }      this.defaultConversionService = conversionService;    }    return this.defaultConversionService;  }

获取默认的转换器

org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.ValidatedLocalValidatorFactoryBean 支持Validated注解的LocalValidatorFactoryBean

@Override    public boolean supports(Class> type) {      if (!super.supports(type)) {        return false;      }      if (AnnotatedElementUtils.hasAnnotation(type, Validated.class)) {        return true;      }      if (type.getPackage() != null && type.getPackage().getName()          .startsWith("org.springframework.boot")) {        return false;      }      if (getConstraintsForClass(type).isBeanConstrained()) {        logger.warn("The @ConfigurationProperties bean " + type            + " contains validation constraints but had not been annotated "            + "with @Validated.");      }      return true;    }

支持Validated注解

org.springframework.boot.web.servlet.ServletComponentRegisteringPostProcessor 实现了org.springframework.beans.factory.config.BeanFactoryPostProcessor、org.springframework.context.ApplicationContextAware接口,为通过包扫描找到的Servlet组件注册bean的BeanFactoryPostProcessor。

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(ServletComponentScanRegistrar.class)public @interface ServletComponentScan {

启用扫描Servlet组件(过滤器、Servlet和侦听器)。扫描只在使用嵌入式Servlet容器时执行。通常,应该指定值之一basePackages或basepackageclass来控制要扫描组件的包。如果没有它们,将从带有注释的类包中执行扫描。

@AliasFor("basePackages")  String[] value() default {};

basePackages()属性的别名。允许更简洁的注释声明,例如:@ServletComponentScan(“org.my.pkg”)而不是@ServletComponentScan(basePackages=“org.my.pkg”)。

  @AliasFor("value")  String[] basePackages() default {};

扫描带注释的servlet组件的基本包。value()是此属性的别名(并且与此属性互斥)。使用basepackageclass()作为基于字符串的包名称的类型安全替代。

  Class>[] basePackageClasses() default {};

类型安全的basePackages()替代方法,用于指定要扫描的包,以查找带注释的servlet组件。将扫描指定的每个类的包。

org.springframework.boot.web.servlet.ServletComponentScanRegistrar 基于ServletComponentScan注解的ImportBeanDefinitionRegistrar实现

  @Override  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,      BeanDefinitionRegistry registry) {//    获取指定的包名    Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);//    是否包含servletComponentRegisteringPostProcessor BeanDefinition    if (registry.containsBeanDefinition(BEAN_NAME)) {      updatePostProcessor(registry, packagesToScan);    }    else {      addPostProcessor(registry, packagesToScan);    }  }

如果包含servletComponentRegisteringPostProcessor BeanDefinition更新BeanDefinition,如果不添加servletComponentRegisteringPostProcessor BeanDefinition,org.springframework.boot.web.servlet.ServletComponentScanRegistrar#updatePostProcessor 更新BeanDefinition

private void updatePostProcessor(BeanDefinitionRegistry registry,      Set<String> packagesToScan) {//    获得servletComponentRegisteringPostProcessor BeanDefinition    BeanDefinition definition = registry.getBeanDefinition(BEAN_NAME);//    获得set类型的构造参数值    ValueHolder constructorArguments = definition.getConstructorArgumentValues()        .getGenericArgumentValue(Set.class);    @SuppressWarnings("unchecked")    Set<String> mergedPackages = (Set<String>) constructorArguments.getValue();    mergedPackages.addAll(packagesToScan);    constructorArguments.setValue(mergedPackages);  }

org.springframework.boot.web.servlet.ServletComponentScanRegistrar#addPostProcessor 添加BeanDefinition

  private void addPostProcessor(BeanDefinitionRegistry registry,      Set<String> packagesToScan) {//    创建ServletComponentRegisteringPostProcessor BeanDefinition    GenericBeanDefinition beanDefinition = new GenericBeanDefinition();    beanDefinition.setBeanClass(ServletComponentRegisteringPostProcessor.class);//    设置ServletComponentRegisteringPostProcessor BeanDefinition的构造参数值    beanDefinition.getConstructorArgumentValues()        .addGenericArgumentValue(packagesToScan);    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);//    注册servletComponentRegisteringPostProcessor BeanDefinition    registry.registerBeanDefinition(BEAN_NAME, beanDefinition);  }
private Set<String> getPackagesToScan(AnnotationMetadata metadata) {//    获取@ServletComponentScan属性    AnnotationAttributes attributes = AnnotationAttributes.fromMap(        metadata.getAnnotationAttributes(ServletComponentScan.class.getName()));    String[] basePackages = attributes.getStringArray("basePackages");    Class>[] basePackageClasses = attributes.getClassArray("basePackageClasses");    Set<String> packagesToScan = new LinkedHashSet<String>();    packagesToScan.addAll(Arrays.asList(basePackages));    for (Class> basePackageClass : basePackageClasses) {//      获取类的包名      packagesToScan.add(ClassUtils.getPackageName(basePackageClass));    }    if (packagesToScan.isEmpty()) {      packagesToScan.add(ClassUtils.getPackageName(metadata.getClassName()));    }    return packagesToScan;  }

获取ServletComponentScan注解指定的包名

private static final List HANDLERS;

HANDLERS

  static {    List servletComponentHandlers = new ArrayList();    servletComponentHandlers.add(new WebServletHandler());    servletComponentHandlers.add(new WebFilterHandler());    servletComponentHandlers.add(new WebListenerHandler());    HANDLERS = Collections.unmodifiableList(servletComponentHandlers);  }

添加handler

org.springframework.boot.web.servlet.ServletComponentHandler 通过类路径扫描发现的Servlet组件处理程序的抽象基类。

  private final Class extends Annotation> annotationType;

annotationType

protected String[] extractUrlPatterns(String attribute,      Map<String, Object> attributes) {    String[] value = (String[]) attributes.get("value");    String[] urlPatterns = (String[]) attributes.get("urlPatterns");    if (urlPatterns.length > 0) {      Assert.state(value.length == 0,          "The urlPatterns and value attributes are mutually exclusive.");      return urlPatterns;    }    return value;  }

提取value值和urlPatterns参数值

protected final Map<String, String> extractInitParameters(      Map<String, Object> attributes) {    Map<String, String> initParameters = new HashMap<String, String>();    for (AnnotationAttributes initParam : (AnnotationAttributes[]) attributes        .get("initParams")) {      String name = (String) initParam.get("name");      String value = (String) initParam.get("value");      initParameters.put(name, value);    }    return initParameters;  }

提取initParams初始化参数值

void handle(ScannedGenericBeanDefinition beanDefinition,      BeanDefinitionRegistry registry) {    Map<String, Object> attributes = beanDefinition.getMetadata()        .getAnnotationAttributes(this.annotationType.getName());    if (attributes != null) {//      模板方法      doHandle(attributes, beanDefinition, registry);    }  }

操作handler,这里是模板方法实现,org.springframework.boot.web.servlet.ServletComponentHandler#doHandle 子类需要实现这个模板方法

protected abstract void doHandle(Map<String, Object> attributes,      ScannedGenericBeanDefinition beanDefinition, BeanDefinitionRegistry registry);

org.springframework.boot.web.servlet.WebServletHandler 基于WebServlet注解处理的类

@Override  public void doHandle(Map<String, Object> attributes,      ScannedGenericBeanDefinition beanDefinition,      BeanDefinitionRegistry registry) {//    创建ServletRegistrationBean BeanDefinition    BeanDefinitionBuilder builder = BeanDefinitionBuilder        .rootBeanDefinition(ServletRegistrationBean.class);//    是否支持异步    builder.addPropertyValue("asyncSupported", attributes.get("asyncSupported"));//    初始化参数    builder.addPropertyValue("initParameters", extractInitParameters(attributes));//    启动顺序    builder.addPropertyValue("loadOnStartup", attributes.get("loadOnStartup"));//    servlet名称    String name = determineName(attributes, beanDefinition);    builder.addPropertyValue("name", name);//    添加servlet    builder.addPropertyValue("servlet", beanDefinition);//    路径映射    builder.addPropertyValue("urlMappings",        extractUrlPatterns("urlPatterns", attributes));//    解析@MultipartConfig注解,加载MultipartConfigElement bean定义    builder.addPropertyValue("multipartConfig",        determineMultipartConfig(beanDefinition));//    注册BeanDefinition    registry.registerBeanDefinition(name, builder.getBeanDefinition());  }

创建BeanDefinition

  private MultipartConfigElement determineMultipartConfig(      ScannedGenericBeanDefinition beanDefinition) {    Map attributes = beanDefinition.getMetadata()        .getAnnotationAttributes(MultipartConfig.class.getName());    if (attributes == null) {      return null;    }    return new MultipartConfigElement((String) attributes.get("location"),        (Long) attributes.get("maxFileSize"),        (Long) attributes.get("maxRequestSize"),        (Integer) attributes.get("fileSizeThreshold"));  }

解析MultipartConfigElement,解析上传文件路径,最大文件大小,最大请求文件大小,文件最大阈值

org.springframework.boot.web.servlet.WebFilterHandler 基于WebFilter注解的handler

  @Override  public void doHandle(Map<String, Object> attributes,      ScannedGenericBeanDefinition beanDefinition,      BeanDefinitionRegistry registry) {//    创建BeanDefinition    BeanDefinitionBuilder builder = BeanDefinitionBuilder        .rootBeanDefinition(FilterRegistrationBean.class);//    是否支持异步    builder.addPropertyValue("asyncSupported", attributes.get("asyncSupported"));//    转发类型    builder.addPropertyValue("dispatcherTypes", extractDispatcherTypes(attributes));//    添加filter    builder.addPropertyValue("filter", beanDefinition);//    初始化参数    builder.addPropertyValue("initParameters", extractInitParameters(attributes));//    设置filter名称    String name = determineName(attributes, beanDefinition);    builder.addPropertyValue("name", name);//    servlet名称    builder.addPropertyValue("servletNames", attributes.get("servletNames"));//    路径映射    builder.addPropertyValue("urlPatterns",        extractUrlPatterns("urlPatterns", attributes));//    注册BeanDefinition     registry.registerBeanDefinition(name, builder.getBeanDefinition());  }

创建BeanDefinition

private EnumSet extractDispatcherTypes(      Map attributes) {    DispatcherType[] dispatcherTypes = (DispatcherType[]) attributes        .get("dispatcherTypes");    if (dispatcherTypes.length == 0) {      return EnumSet.noneOf(DispatcherType.class);    }    if (dispatcherTypes.length == 1) {      return EnumSet.of(dispatcherTypes[0]);    }    return EnumSet.of(dispatcherTypes[0],        Arrays.copyOfRange(dispatcherTypes, 1, dispatcherTypes.length));  }

提取转发类型

private String determineName(Map<String, Object> attributes,      BeanDefinition beanDefinition) {    return (String) (StringUtils.hasText((String) attributes.get("filterName"))        ? attributes.get("filterName") : beanDefinition.getBeanClassName());  }

解析filter名称

org.springframework.boot.web.servlet.WebListenerHandler 基于WebListener注解的handler

@Override  protected void doHandle(Map<String, Object> attributes,      ScannedGenericBeanDefinition beanDefinition,      BeanDefinitionRegistry registry) {//    创建BeanDefinition    BeanDefinitionBuilder builder = BeanDefinitionBuilder        .rootBeanDefinition(ServletListenerRegistrationBean.class);//    添加listener    builder.addPropertyValue("listener", beanDefinition);//    注册BeanDefinition    registry.registerBeanDefinition(beanDefinition.getBeanClassName(),        builder.getBeanDefinition());  }

创建BeanDefinition

private final Set<String> packagesToScan;

扫描的路径

  private ApplicationContext applicationContext;

applicationContext

@Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)      throws BeansException {    if (isRunningInEmbeddedContainer()) {      ClassPathScanningCandidateComponentProvider componentProvider = createComponentProvider();      for (String packageToScan : this.packagesToScan) {//        扫描包路径的BeanDefinition        scanPackage(componentProvider, packageToScan);      }    }  }

重写org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory方法,扫描指定包路径的BeanDefinition

private void scanPackage(      ClassPathScanningCandidateComponentProvider componentProvider,      String packageToScan) {//    扫描包路径的beanDefinition    for (BeanDefinition candidate : componentProvider        .findCandidateComponents(packageToScan)) {      if (candidate instanceof ScannedGenericBeanDefinition) {        for (ServletComponentHandler handler : HANDLERS) {//          调用handler逻辑          handler.handle(((ScannedGenericBeanDefinition) candidate),              (BeanDefinitionRegistry) this.applicationContext);        }      }    }  }

扫描指定包名的BeanDefinition,执行handler逻辑

@Override  public void setApplicationContext(ApplicationContext applicationContext)      throws BeansException {    this.applicationContext = applicationContext;  }

重写org.springframework.context.ApplicationContextAware#setApplicationContext方法,设置applicationContext

org.springframework.boot.web.servlet.ErrorPageRegistrarBeanPostProcessor 实现了org.springframework.beans.factory.config.BeanPostProcessor、org.springframework.beans.factory.BeanFactoryAware接口。

将bean工厂中的所有ErrorPageRegistrars应用于ErrorPageRegistry bean的BeanPostProcessor。

  private ListableBeanFactory beanFactory;

beanFactory

@Override  public void setBeanFactory(BeanFactory beanFactory) {    Assert.isInstanceOf(ListableBeanFactory.class, beanFactory,        "ErrorPageRegistrarBeanPostProcessor can only be used "            + "with a ListableBeanFactory");    this.beanFactory = (ListableBeanFactory) beanFactory;  }

重写org.springframework.beans.factory.BeanFactoryAware#setBeanFactory方法,设置beanFactory

@Override  public Object postProcessBeforeInitialization(Object bean, String beanName)      throws BeansException {    if (bean instanceof ErrorPageRegistry) {      postProcessBeforeInitialization((ErrorPageRegistry) bean);    }    return bean;  }

重写org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization方法,org.springframework.boot.web.servlet.ErrorPageRegistrarBeanPostProcessor#postProcessBeforeInitialization(org.springframework.boot.web.servlet.ErrorPageRegistry)

private void postProcessBeforeInitialization(ErrorPageRegistry registry) {    for (ErrorPageRegistrar registrar : getRegistrars()) {//      注册errorPage      registrar.registerErrorPages(registry);    }  }

获取错误页面注册器注册错误页面,org.springframework.boot.web.servlet.ErrorPageRegistrarBeanPostProcessor#getRegistrars

private Collection getRegistrars() {    if (this.registrars == null) {      // Look up does not include the parent context//      设置BeanFactory中获取ErrorPageRegistrar      this.registrars = new ArrayList(this.beanFactory          .getBeansOfType(ErrorPageRegistrar.class, false, false).values());      Collections.sort(this.registrars, AnnotationAwareOrderComparator.INSTANCE);      this.registrars = Collections.unmodifiableList(this.registrars);    }    return this.registrars;  }
@Override  public Object postProcessAfterInitialization(Object bean, String beanName)      throws BeansException {    return bean;  }

重写org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization方法,bean初始化后不做处理

说在最后

本次解析仅代表个人观点,仅供参考。

ca99450a2b0f1fb15e4914deab1dc0f0.gif

扫码进入技术微信群

e426aa35b497aa5205eca845fc997bf5.png 2d1d645319f0ec02115dd074844ef1b0.png 4e9d7263b6490691406538cf45c61654.png钉钉技术群

6b79cb2071913a1e16106a6d9e2dcfdf.png

qq技术群

6fac2cf2f0e204515413b9670456c0f1.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值