当前位置: 首页 > wzjs >正文

怎么查网站开发使用的语言正能量网站窗口免费进

怎么查网站开发使用的语言,正能量网站窗口免费进,嵌入式是什么,网站建设典型经验这是学透Spring Boot的第14篇文章,更多文章请移步我的专栏: 学透 Spring Boot_postnull咖啡的博客-CSDN博客 目录 没有Spring Boot时的Spring MVC 使用Spring Boot后的Spring MVC Spring MVC的自动配置解析 明确目标 入口类 Spring容器的启动 S…

这是学透Spring Boot的第14篇文章,更多文章请移步我的专栏:

学透 Spring Boot_postnull咖啡的博客-CSDN博客

目录

没有Spring Boot时的Spring MVC

使用Spring Boot后的Spring MVC

Spring MVC的自动配置解析

明确目标

入口类

Spring容器的启动

Spring容器生命周期hook类

配置类解析类 ConfigurationClassParser

自动配置类列表 AutoConfiguration.imports

Spring MVC的自动配置类WebMvcAutoConfiguration

自动配置的视图解析器 

Http消息转换器自动配置类

数据源自动配置类 DataSourceAutoConfiguration

RestClient的自动配置 RestClientAutoConfiguration

嵌入式的web容器配置 

DispatcherServlet的自动配置

总结


没有Spring Boot时的Spring MVC

早些年还没有Spring Boot的时候,我们开发一个Spring MVC应用,需要做一大堆的配置,而且和其它的项目比较,这些配置大部分都是大同小异的,我们也可以称之为样板配置。

所以每次新建一个项目,我们通常是复制一个项目,然后复制这个项目的配置,做少量的修改,虽然没有什么太大的问题,但是如果一不小心改错,可能半天都找不到问题。

可以参考之前的一篇文章,里面介绍了没有Spring Boot时完整的手动配置。

学透Spring Boot — [二] Spring 和 Spring Boot的比较-CSDN博客

我们可以大概看看传统Spring MVC项目的配置

web.xml 中配置DispatchServlet

在 servlet-context.xml 中配置 Spring MVC 相关组件

这两份配置,非常冗余,因为绝大部分项目都大同小异。

最后再实现控制器

使用Spring Boot后的Spring MVC

如果使用Spring Boot,事情变得非常简单。

我们只要在我们的应用启动类添加一个注解 @SpringBootApplication

然后,所有的事情,SpringBoot都会自动帮我们完成。

简直是单车 到 摩托车的飞跃。

Spring MVC的自动配置解析

下面我们一步步来研究,Spring Boot是如何做到自动配置MVC的。

明确目标

自动配置的结果,就是把手动显示的配置,变成自动的配置。

比如servlet-context.xml中配置的视图解析器

Spring Boot 它会通过@Bean声明的方式,帮我们创建一个视图解析器的Bean

我们今天的任务,就是要搞清楚,Spring Boot在哪里以及什么时候,帮我创建的这个Bean。

入口类

首先我们的入口类,使用了一个注解@SpringBootApplication。

@SpringBootApplication
public class JoeLabApplication {public static void main(String[] args) {SpringApplication.run(JoeLabApplication.class, args);}
}

它其实是个组合注解。

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {

我们重点关注@EnableAutoConfiguration 这个注解,它是一个总开关,开启了自动配置的新世界。

这个注解也是一个组合注解。

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

通过@Import(AutoConfigurationImportSelector.class)这个注解,会触发自动配置类的导入,spring boot会用这个类去完成自动配置的功能。

Spring容器的启动

这次,我们先看看Spring Boot的启动,来分析自动配置是如何生效。

public class SpringApplication {public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class<?>[] { primarySource }, args);}
}

SpringBoot的run方法,会创建并刷新Spring容器。

public ConfigurableApplicationContext run(String... args) {context = createApplicationContext();context.setApplicationStartup(this.applicationStartup);prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);refreshContext(context); // 刷新 Spring 容器,加载各种 BeanafterRefresh(context, applicationArguments);startup.started();
}

关注:refreshContext(context); // 刷新 Spring 容器,加载各种 Bean

接着刷新容器

刷新容器的关键过程包括 Bean 的加载与初始化。refreshContext 方法会启动各类 Bean 的生命周期,调用 invokeBeanFactoryPostProcessors 来执行 BeanFactory 后处理器。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}
}

重点关注:invokeBeanFactoryPostProcessors

我们理解成Spring提供的生命周期钩子就行。通过这些钩子,我们可以在Spring启动过程中,做一些特殊的工作。比如自动化配置各种bean。

Spring容器生命周期hook类

其中Spring就提供了一个钩子类。

它是生命周期类,所以启动过程中自动被找到并执行。

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanRegistrationAotProcessor, BeanFactoryInitializationAotProcessor, PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {
}

这个类会去处理配置类 也就是加了@Configuration的类

    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");parser.parse(candidates);parser.validate();}

配置类解析类 ConfigurationClassParser

接下来,它把任务交给了解析器——ConfigurationClassParser

最终这个解析工具类,通过一长串的调用链,最终到了另一个工具类ImportCandidates

public final class ImportCandidates implements Iterable<String> {public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {Assert.notNull(annotation, "'annotation' must not be null");ClassLoader classLoaderToUse = decideClassloader(classLoader);String location = String.format(LOCATION, annotation.getName());Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);List<String> importCandidates = new ArrayList<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();importCandidates.addAll(readCandidateConfigurations(url));}return new ImportCandidates(importCandidates);}
}

我们重点看这一行代码

String location = String.format(LOCATION, annotation.getName());

其中:private static final String LOCATION = "META-INF/spring/%s.imports";

所以location是:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

这个文件,在我们的自动配置模块下

自动配置类列表 AutoConfiguration.imports

我们把这个文件的内容罗列出来

是不是很多名字都似曾相识呢?

是的,这就是SpringBoot提供的自动配置类,对各种常用的组件,都提供了自动配置类。

SpringBoot在启动Spring容器的过程中,会定位到这个文件,然后逐个尝试去加载配置类。

Spring MVC的自动配置类WebMvcAutoConfiguration

我们先重点关注其中一个WebMvcAutoConfiguration

这个类提就是Spring MVC的自动配置类。

这个配置类会被找到,但是要不要加载,得看条件。条件配置就是它上面的注解。

我们逐条解析:

@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
        ValidationAutoConfiguration.class }

DispatcherServlet配置完后,才会配置Spring MVC。

说得通,就像我们先配置web.xml中的DispatcherServlet,再配置Spring mvc的配置servlet.xml

@ConditionalOnWebApplication(type = Type.SERVLET)

必须是Spring MVC(Servlet)的web才会加载。

如果是WebFlux的web,就不会自动配置MVC。

@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })

Classpath下有这个两个类。

表示我们引入了Spring mvc的依赖。

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

只有当Spring容器没有WebMvcConfigurationSupport这个bean时,才会配置MVC。

因为这个Bean是用来给我们自定义的,如果我们不想用自动配置,而是想覆盖默认配置,我们就需要继承这个类。这样,SpringBoot就以我们配置的为主,而忽略自动配置。

这些条件,我们都满足,所以Spring Boot开始用这个类进行自动配置MVC。

这个配置类中定义了很多Bean,这些bean就是MVC的组件。

自动配置的视图解析器 

其中,就包含默认的视图解析器。

		@Bean@ConditionalOnMissingBeanpublic InternalResourceViewResolver defaultViewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix(this.mvcProperties.getView().getPrefix());resolver.setSuffix(this.mvcProperties.getView().getSuffix());return resolver;}

还记得我们在传统Spring MVC项目手动的配置吗?是的,我们做到了,通过自动创建Bean的方式,成功完成了视图解析器的配置。

我们在看看其它的自动配置类。

都定义在org.springframework.boot.autoconfigure.AutoConfiguration.imports这个文件下。

Http消息转换器自动配置类

@AutoConfiguration(after = { GsonAutoConfiguration.class, JacksonAutoConfiguration.class, JsonbAutoConfiguration.class })
@ConditionalOnClass(HttpMessageConverter.class)
@Conditional(NotReactiveWebApplicationCondition.class)
@Import({ JacksonHttpMessageConvertersConfiguration.class, GsonHttpMessageConvertersConfiguration.class,JsonbHttpMessageConvertersConfiguration.class })
@ImportRuntimeHints(HttpMessageConvertersAutoConfigurationRuntimeHints.class)
public class HttpMessageConvertersAutoConfiguration {

它导入了三种解析器

@Import({ JacksonHttpMessageConvertersConfiguration.class,         GsonHttpMessageConvertersConfiguration.class,JsonbHttpMessageConvertersConfiguration.class })

其中Jackson的是

		@Bean@ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class,ignoredType = {"org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter","org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" })MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {return new MappingJackson2HttpMessageConverter(objectMapper);}

数据源自动配置类 DataSourceAutoConfiguration

	@Configuration(proxyBeanMethods = false)@Conditional(PooledDataSourceCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })protected static class PooledDataSourceConfiguration {@Bean@ConditionalOnMissingBean(JdbcConnectionDetails.class)PropertiesJdbcConnectionDetails jdbcConnectionDetails(DataSourceProperties properties) {return new PropertiesJdbcConnectionDetails(properties);}}

RestClient的自动配置 RestClientAutoConfiguration

	@Bean@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)@ConditionalOnMissingBeanRestClient.Builder restClientBuilder(RestClientBuilderConfigurer restClientBuilderConfigurer) {return restClientBuilderConfigurer.configure(RestClient.builder());}

嵌入式的web容器配置 

@AutoConfiguration
@ConditionalOnNotWarDeployment
@ConditionalOnWebApplication
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {/*** Nested configuration if Tomcat is being used.*/@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })public static class TomcatWebServerFactoryCustomizerConfiguration {@Beanpublic TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment,ServerProperties serverProperties) {return new TomcatWebServerFactoryCustomizer(environment, serverProperties);}@Bean@ConditionalOnThreading(Threading.VIRTUAL)TomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() {return new TomcatVirtualThreadsWebServerFactoryCustomizer();}}

DispatcherServlet的自动配置

		@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {DispatcherServlet dispatcherServlet = new DispatcherServlet();dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails());return dispatcherServlet;}

总结

我们这篇文章,从另一个角度——Spring容器的启动过程,结合SpringBoot提供的注解,理解了Spring Boot的自动配置原理。

最终定义到自动配置类的列表文件:

org.springframework.boot.autoconfigure.AutoConfiguration.imports

http://www.dtcms.com/wzjs/590100.html

相关文章:

  • 温州市微网站制作多少钱利用大平台做网站
  • 网站运营方案书做网站的公司属于什么行业
  • 浙江网站建设上市公司建网站买完域名后怎么做
  • 做返利网站能赚钱网站中微信公众号链接怎么做
  • 网站开发市场情况网站打开显示建设中
  • 广州网站建设weeken中牟网站制作
  • 网站建设价格方案网站建设氺首选金手指14
  • 东莞市建设工程质量监督网站品牌注册证
  • p2p网站建设小微金融凡客官网登录入口网址
  • 企业网站特色建设企业文化建设网站
  • 科技政策要聚焦自立自强seo综合查询是什么
  • 网站升级通知自动跳跃帝国cms网站地图xml
  • 黑龙江省建设厅官方网站舟山论坛网站建设
  • 公众号免费素材网站黑龙江建筑工程网
  • 北京网站建设q479185700強杭州四喜做网站建设么
  • 聊城哪里有做网站的wordpress接入翼支付宝
  • 管理咨询公司企业文化网站排名优化系统
  • 更换网站程序黄山网站建设电话
  • 网站搭建教学上海人才服务网官网
  • 一个好的网站建设厚街网站建设报价
  • 做订餐网站数据库应该有哪些表如何制作小程序下单
  • 织梦网站装修公司源码好用的免费网站
  • 网站建站工具有哪些介绍网站设计风格
  • 做关键词优化需要修改网站标题网站建设关闭窗口代码
  • 饮食网站开发需求深圳外贸soho网站建设
  • 个人直播网站开发能制作网站的公司联系方式
  • 百度商桥怎么添加到网站免费广告投放平台
  • 体育网站建设青岛网站建设谁家好一些
  • 网站建设报价明细单优化网站作用
  • 做网站用windows和 linux重庆市建设施工程信息网