说在前面
前期回顾
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 源码解析 更新完毕
源码解析
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](https://i-blog.csdnimg.cn/blog_migrate/6a210b82027813fd2f4c76c406ce9aaa.gif)
扫码进入技术微信群
![e426aa35b497aa5205eca845fc997bf5.png](https://i-blog.csdnimg.cn/blog_migrate/5fb1cece84b64715267cab883dca45ae.jpeg)
![2d1d645319f0ec02115dd074844ef1b0.png](https://i-blog.csdnimg.cn/blog_migrate/b5ec4630caa00b39c9cfe6e4d4e484d0.png)
![4e9d7263b6490691406538cf45c61654.png](https://i-blog.csdnimg.cn/blog_migrate/dd93a537249c0432c62f8c257fa9d4c3.png)
qq技术群