江门移动网站建设多少钱网站虚拟主机建设
web/
2025/10/5 1:28:39/
文章来源:
江门移动网站建设多少钱,网站虚拟主机建设,wordpress文章排序插件,wordpress 是什么呢Spring的了解与特性 简单介绍#xff1a;快速开发Spring项目的脚手架。简化Spring应用的初始搭建以及开发过程。 特性 提供了很多内置的Starter结合自动配置#xff0c;对主流框架的无配置集成、开箱即用。即不需要自己去引入很多依赖。 并且管理了常用的第三方依赖的版本快速开发Spring项目的脚手架。简化Spring应用的初始搭建以及开发过程。 特性 提供了很多内置的Starter结合自动配置对主流框架的无配置集成、开箱即用。即不需要自己去引入很多依赖。 并且管理了常用的第三方依赖的版本减少了版本冲突的问题。 简化开发采用JavaConfig的方式可以使用0xml方式进行开发。 内置Web容器无需依赖外部Web服务器省略了Web.xml直接运行就使Web应用。 提供了监控功能可以监控应用程序的运行状态、内存、线程池、HTTP请求统计等。 Spring与SpringBoot的关系 两者都是Spring生态的产品 前者是容器框架后者是一个快速开发Spring的脚手架真正意义上不算新的框架 核心注解 SpringBootApplication SpringBootConfiguration标记为配置类的注解 Configuration EnableAutoConfiguration向Spring容器中导入了一个Selector用来加载ClassPath下SpringFactories中所定义的配置类将这些自动加载为配置Bean。 Conditional待补充
自动配置原理 通过SpringBootApplication中的EnableAutoConfiguration EnableAutoConfiguration引入了Import 在Spring容器启动时会加载IoC容器解析Import注解 Import导入了DeferredImportSeletor注解会使SpringBoot的自动配置类的顺序在最后方便扩展的覆盖 读取META-INF/spring.factories文件 过滤出所有的AutoConfigurationClass类型的类 最后通过Condition排除无效的自动配置类 为什么SpringBoot的jar可以直接运行 部署SpringBoot的插件才能将package后的jar包使用java -jar packageName运行 也就是在pom.xml中要有build中的plugins中plugin的spring-boot-maven-plugin。如果没有这个插件在运行命令的时候会报没有主清单属性。 使用插件打包后生成的其实是一个Fat jar也就是jar包中还有jar包包含了应用依赖的jar包和Spring Boot Loader相关的类。 java - jar会去找jar中的MANIFEST.MF文件在那里面找到真正的启动类Main-Class。 Fat jar的启动Main函数是JarLauncher它负责创建一个LaunchedURLClassLoader加载boot-lib下面的jar并以一个新的线程启动应用Main函数其实就是找到MANIFEST中的Start-Class。 当然为了去验证此说法就需要引入依赖从而去看JarLauncher中的源码引入此依赖后再package就可以查看源码了。 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-loader/artifactId
/dependency
启动原理 运行主启动类的main方法会初始化SpringApplication从spring.factories读取listener ApplicationContextInitializer。此primarySources就是当前SpringBoot项目的class文件。 在初始化SpringApplication中对一些属性的初始化比如开启日志记录、关闭懒加载等等。不同版本的Boot在初始化的时候不一样主要是最下面的七行。以下讲解最下面五行的作用。就不根据源码展示了。 将启动类primarySources放入到名为primartSrouces的LinkedHashSet集合中 推算当前Web应用类型webApplicationType 读取ApplicationContextInitializer初始化器 读取ApplicationListener监听器 将Main方法所在的类放入mainApplicationClass中 接下来就是运行run()方法了。代码太多就不展示了。主要是做了以下的操作 从上面读取的ApplicationListener监听器去读取SpringApplicationRunListener监听器运行器 发布ApplicationStartingEvent事件 封装命令行参数ApplicationArguments 读取环境配置信息 根据webApplicationType创建环境变量对象 配置环境变量 将现有环境信息设置为ConfigurationProperties的数据源 并且放在第一位 发布ApplicationEnvironmentPreparedEvent事件 将spring.main的配置绑定到SpringApplication属性上 将现有的环境信息设置为ConfigurationProperties的数据源 更新放在第一位 设置忽略bean.spring.beaninfo.ignore 打印Banner 实例化Spring上下文 AnnotationConfigServletWebServerApplicationContext 初始化失败分析器 准备上下文将启动类作为配置类进行读取 - 将配置注册为BeanDefinition 将当前环境信息设置到context 调用ApplicationContextInitializer 发布ApplicationContextInitializerdEvent事件 打印启动信息和profile.active测试/生产/开发信息 将applicationArguments、printedBanner注册为Bean 设置不允许同名Bean 设置是否懒加载Bean 读取启动类为BeanDefinition 将SpringBoot的监听器添加到context发布 ApplicationPreparedEvent事件 加载IoC容器(refresh()方法)其中的十二个步骤。具体干了什么可以去看我另外几篇源码解读的博文。主要两个方法 invokeBeanFactoryPostProcessor() - 解析Import 加载所有的自动配置类 onRefresh() 创建内置的Servlet容器 待扩展刷新后的处理 发布ApplicationStartedEvent事件发布ApplicationReadyEvent事件 如果启动异常会发送ApplicationFailedEvent事件
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch new StopWatch();stopWatch.start();ConfigurableApplicationContext context null;CollectionSpringBootExceptionReporter exceptionReporters new ArrayList();this.configureHeadlessProperty();// 从上面读取的ApplicationListener监听器去读取SpringApplicationRunListener监听器运行器SpringApplicationRunListeners listeners this.getRunListeners(args);// 发布ApplicationStartingEvent事件listeners.starting();
Collection exceptionReporters;try {// 封装命令行参数ApplicationArgumentsApplicationArguments applicationArguments new DefaultApplicationArguments(args);// 读取环境配置信息ConfigurableEnvironment environment this.prepareEnvironment(listeners, applicationArguments);// 设置忽略bean.spring.beaninfo.ignore this.configureIgnoreBeanInfo(environment);// 打印BannerBanner printedBanner this.printBanner(environment);// 实例化Spring上下文 AnnotationConfigServletWebServerApplicationContextcontext this.createApplicationContext();// 初始化失败分析器exceptionReporters this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);// 准备上下文将启动类作为配置类进行读取 - 将配置注册为BeanDefinitionthis.prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 加载IoC容器this.refreshContext(context);// 待扩展刷新后的处理this.afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);}
// 发布ApplicationStartedEvent事件listeners.started(context);this.callRunners(context, applicationArguments);} catch (Throwable var10) {this.handleRunFailure(context, var10, exceptionReporters, listeners);throw new IllegalStateException(var10);}
try {// 发布ApplicationReadyEvent事件listeners.running(context);return context;} catch (Throwable var9) {this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);throw new IllegalStateException(var9);}
}
内置Tomcat启动原理 当依赖spring-boot-starter-web依赖时会在SpringBoot中添加ServletWebServerFactoryAutoConfigurationservlet容器自动配置类 该自动配置类通过Import导入了可用的通过ConditionalOnClass判断决定使用哪一个的Web容器工厂默认Tomcat 在内嵌的Tomcat类中配置了一个TomcatServletWebServerFactory的BeanWeb容器工厂 它会在SpringBoot启动时加载IoC容器、在onRefrush()方法中创建内嵌的Tomcat并启动
外部Tomcat启动原理 SpringBoot启动后会加载SpringServletContainerInitializer类此类会去加载实现了WebApplicationInitializer接口的类而其中SpringBootServletInitializer这个类就实现了这个接口而需要继承这个类去传入当前应用的启动类。
WebApplicationContext rootAppContext this.createRootApplicationContext(servletContext); 想要使用外部的Tomcat就需要排除内部的Tomcat。
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusionsexclusiongroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-tomcat/artifactId/exclusion/exclusions
/dependency 创建一个配置类去继承SpringBootServletInitializer去重写configure()方法将当前模块的启动类传入进去 。
public class TomcatConfig extends SpringBootServletInitializer {Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {return builder.sources(StudySpringApplication.class);}
}
如何自定义Starter 首先知道什么是StarterStarter又名启动器。众所周知SpringBoot是简化了企业级Spring框架的开发采用了约定优于配置的理念而这个理念的实现就是用Starter组件。其会把对应功能的jar包导入进来使得开发者无需在意版本冲突问题而只需在乎业务逻辑即可这是作为引入依赖方面的简化配置。而此处要介绍的Starter就是代替Spring的内部组件使用自定义的组件去完成启动。步骤如下 新建resources/META-INF/spring.factories。这是因为Spring Boot在启动的时候会去读取ClassPath下的这个文件信息。 在spring.factories中去用伪SPI去扫描我们自定义的Starter启动器组件 读取配置文件的原理以及加载顺序 通过事件监听的方式读取配置文件而读取配置文件的类则是ConfigFileApplicationListener 读取配置文件的方式 属性上使用注解Value(${xxx.yyy})需要注意三点 当前类是交给IoC容器管理的Bean否则Value注解不生效。 当前属性不能是static或者final修饰。 如果配置文件中没有对应的xxx: yyy的话会报错但是可以在Value中给默认值比如Value(${xxx.yyy:})这样默认为 缺点是一个属性对应一个如果需要读取多个属性的话效率低下。 类上使用注解ConfigurationProperties(prefix xxx)去指定配置文件中的前缀去读取多个然后属性采用同名方式去进行批量匹配。相比于上面那种而言如果遇到大量的配置信息则效率会更高。
ConfigurationProperties(prefix xxx)
public class MyYamlConfig {private String yyy;
} 通过Spring的应用上下文ApplicationContext去获取Environment对象。但相较于直接获取Environment对象这样显得多此一举除非除了要使用ApplicationContext获取运行时环境还有其它的作用。毕竟ApplicationContext是Spring应用程序中的中央接口由于继承了多个组件所以有多个核心的功能。 Spring Bean类中去注入IoC管理的Environment对象。可以使用Resource、Autowired来注入。然后在代码块中通过此对象的getProperty(xxx.yyy)返回String对象进行使用即可。但是如果不用自动装配的方式也就是非Spring管理的Bean就需要此配置类去实现EnvironmentAware接口重写setEnvironment()方法去获取Environment对象。 配置类上获取外部properties后缀配置文件的方式比如需要读取/resources/gok.properties文件。在配置类上使用注解PropertySources。然后就可以在属性上使用Value注解去读取。
Configuraion
PropertySources({propertySource(value classpath:gok.properties, encoding UTF-8)})
public class MyYamlConfig {Value(${xxx.yyy})private String name;
} 获取/resources/gok.yml文件。在被Configuration注解的配置类去配置
Configuration
public class MyYamlConfig {Beanpublic static PropertySourcesPlaceholderConfigurer yamlConfigurer() {PropertySourcesPlaceholderConfigurer configurer new PropertySourcesPlaceholderConfigurer();YamlPropertiesFactoryBean yaml new yamlPropertiesFactoryBean();yaml.setResources(new ClassPathResource(gok.yml));configurer.setProperties(Object.requireNonNull(yaml.getObject()));return configurer;}
} 采用Java原生态的方式InputStream流去读取文件
public class MyYamlConfig {public void yamlConfigurer() {Properties props new Properties();try {InputStreamReader reader new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(gok.properties),StandardCharsets.UTF_8);props.load(reader);} catch (IOException e) {}String name props.getProperty(xxx.yyy);}
}
解决跨域的方式 首先了解什么是跨域两个URL的协议/域名/IP/端口不同就会产生跨域。跨域是在前端才会发生的问题因为浏览器有一个同源策略这是防止不安全的不同域访问所以会抛出异常也就是跨域问题。 Jsoup 前端使用Ajax的jsoup方式同时后端每个接口的参数都接收一个String callback并且将其放到JSONObject的第一个参数返回。仅支持GET请求而且存在安全问题。 CORS 前端无需多做处理后端有三种方式可以进行实现 在接口上使用CrossOrign注解并且可以带上请求的协议以及域名/IP以及端口比如http://localhost:8080 让配置类(Configuration)去实现WebMvcConfigurer接口重写addCorsMappings()方法。这个的弊端主要是浏览器会自动添加一些附加的头信息甚至还会多发送一次附加的请求第一次就是options第二次才是接口真正调用的请求方法。 Override
public void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**) // 添加映射路径.allowedOriginPatterns(*) // 设置放行哪些原始域 SpringBoot2.4.4低版本使用.allowedOrigins.allowedMethods(GET,HEAD,POST,PUT,DELETE,OPTIONS) // 放行哪些请求方式.allowCredentials(true) // 是否发送Cookie.maxAge(3600).allowedHeaders(*); // 暴露哪些原始请求头部信息
} Nginx 使用反向代理不需要在前后端多做处理不需要添加代码量。只需要在Nginx的nginx.conf文件的server中进行配置这里就略微详细说明一下listen 端口; location /前端路径/ { proxy_pass http://localhost:8080/后端路径 }。
可以同时处理多少请求 在yml中的Tomcat中配置因为这是Spring Boot默认的Web容器。配置与请求线程相关的配置进行测试。 server:tomcat:# 最大连接数max-connections: 30# 最大等待数accept-count: 10threads:# 最少线程数min-spare: 10# 最多线程数max: 50 可以使用ApiPost/JMeter进行并发测试。如下所示就是测试结果。我们不难发现首先执行了30个线程而后先执行完的10个线程又再一次进来执行了。这说明了1s可以处理40次请求并且这40次请求中可以一次性处理30次而最多可以等待10次。即配置中的accept-count最大等待数 max-connections最大连接数。 在spring-configuration-metadata.json中可以发现最大连接数默认为10000最大等待数为100。注意我打开的是SpringBoot2.2.1版本每个版本可能不一样。 默认的日志框架以及如何切换 默认情况下SpringBoot会采用slf4j(日志接口) logback(日志框架)完成日志的实现。那么我们从哪里可以得出来呢看过源码的基本都知道使用LoggerFactory中获取Logger对象从而记录日志的所以我也创建了此对象来记录日志。 而这个LoggerFactory与Logger都是slf4j的日志接口其中slf4j内有三种日志框架logback(默认)、log4j、jul-to-slf4j 那么如何做到切换默认的日志实现框架呢这里有两种情况 将logback切换为lof4j2这样就需要将logback的场景启动器排除因为slf4j这个日志接口只能运行1个桥接器。并且添加log4j2的场景启动器 !-- 如果不是Web应用就在spring-boot-starter中排除依赖 --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusions!-- 排除logback的场景启动器 --exclusiongroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-logging/artifactId/exclusion/exclusions
/dependency!-- Log4j2场景启动器 --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-log4j2/artifactId
/dependency 将logback切换为log4j。就需要将logback的桥接器排除。 !-- 如果不是Web应用就在spring-boot-starter中排除依赖 --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusions!-- 排除logback的场景启动器 --exclusiongroupIdlogback-classic/groupIdartifactIdch.qos.logback/artifactId/exclusion/exclusions
/dependency!-- Log4j桥接器 --
dependencygroupIdorg.slf4j/groupIdartifactIdslf4j-log4j12/artifactId
/dependency
如何优化启动速度 延迟初始化Bean 一般在SpringBoot中拥有很多的耗时任务比如数据库连接、初始化线程池创建等等。我们可以延迟这些操作的初始化来达到优化启动速度的目的。可以在yml中配置spring:main:lazy-initialization: true。来将所有的Bean延迟初始化懒加载机制。 创建扫描索引(Spring 5.0) 通过编译时创建一个静态候选列表来提高大型应用程序的启动性能。在项目中使用Indexed之后编译打包后的时候会在项目中自动生成META-INF/spring.components文件。当Spring应用上下文执行ComponentScan扫描时就会用CandidateComponentsIndexLoader读取这个文件并加载转换为CandidateComponentsIndex对象。 步骤如下引入依赖、启动类加上注解Indexed。首次编译运行后会在/target/classes/META-INF中生成文件 dependencygroupIdorg.springframework/groupIdartifactIdspring-context-indexer/artifactIdoptionaltrue/optional
/dependency 减少ComponentScan即SpringBootApplication扫描类的范围 关闭SpringBoot的JMX监控yml中设置spring:jmx:enabled: false 设置JVM参数 -noverify不对类进行验证 排除项目中多余的依赖jar
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87080.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!