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

有网络网站打不开怎么回事wordpress菜单跳转页面跳转

有网络网站打不开怎么回事,wordpress菜单跳转页面跳转,网络广告策划的步骤,中石油企业邮箱怎么注册背景 本文作为SpringBoot系列的开篇#xff0c;介绍SpringBoot的启动流程#xff0c;包括Spring容器和Tomcat启动过程。SpringBoot作为流行的微服务框架#xff0c;其是基于约定和自动装配机制对Spring的封装和增强。 由于前面的Spring系列对Spring容器已经进行了较为细致的…背景 本文作为SpringBoot系列的开篇介绍SpringBoot的启动流程包括Spring容器和Tomcat启动过程。SpringBoot作为流行的微服务框架其是基于约定和自动装配机制对Spring的封装和增强。 由于前面的Spring系列对Spring容器已经进行了较为细致的梳理相同内容不进行重复说明。 1.案例 添加SpringBoot和web依赖: parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.3.2.RELEASE/version /parentdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency /dependencies启动类 SpringBootApplication // 标注[1] public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);} }Note: 按规范一般将main方法所在的类命名为artifactIdApplication. 2.启动过程 跟踪SpringApplication.run(DemoApplication.class, args): public static ConfigurableApplicationContext run(Class?[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args); }从逻辑上可以拆分为两个部分:构造SpringApplication对象调用SpringApplication对象的run方法. 2.1 构造SpringApplication对象 new SpringApplication(primarySources), primarySources参数为传入的DemoApplication.class对象; 说明传入的primarySources不一定为main方法所在类只需要保证为SpringBootApplication注解的类即可。 经过public SpringApplication(Class?… primarySources) {this(null, primarySources);}进入: public SpringApplication(ResourceLoader resourceLoader, Class?... primarySources) {// resourceLoader为null;this.resourceLoader resourceLoader;// 主配置类此时为DemoApplication.classthis.primarySources new LinkedHashSet(Arrays.asList(primarySources));// web类型为SERVLETthis.webApplicationType WebApplicationType.deduceFromClasspath();// 使用SPI机制加载ApplicationContextInitializer和ApplicationListener类型的对象并保存到initializers和listeners属性中[标注1]setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 推算出main方法所在类(通过构造异常对象获取), 此时为DemoApplication.classthis.mainApplicationClass deduceMainApplicationClass(); }Note: getSpringFactoriesInstances方法逻辑如下: private T CollectionT getSpringFactoriesInstances(ClassT type, Class?[] parameterTypes, Object... args) {ClassLoader classLoader getClassLoader();// 从spring.factories文件中加载指定名称的类型此时为ApplicationContextInitializer和ApplicationListenerSetString names new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 通过反射创建对象ListT instances createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);// 排序(继承了Ordered接口的使用getOrder获取使用Order注解的根据注解的值)AnnotationAwareOrderComparator.sort(instances);return instances; }ApplicationContextInitializer包括 // spring-boot包中的spring.factories文件 org.springframework.context.ApplicationContextInitializer\ org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\ org.springframework.boot.context.ContextIdApplicationContextInitializer,\ org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\ org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\ org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer// spring-boot-autoconfiguration包中的spring.factories文件 org.springframework.context.ApplicationContextInitializer\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListenerApplicationListener包括 // spring-boot包中的spring.factories文件 org.springframework.context.ApplicationListener\ org.springframework.boot.ClearCachesApplicationListener,\ org.springframework.boot.builder.ParentContextCloserApplicationListener,\ org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\ org.springframework.boot.context.FileEncodingApplicationListener,\ org.springframework.boot.context.config.AnsiOutputApplicationListener,\ org.springframework.boot.context.config.ConfigFileApplicationListener,\ org.springframework.boot.context.config.DelegatingApplicationListener,\ org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\ org.springframework.boot.context.logging.LoggingApplicationListener,\ org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener// spring-boot-autoconfiguration包中的spring.factories文件 org.springframework.context.ApplicationListener\ org.springframework.boot.autoconfigure.BackgroundPreinitializer2.2 执行run方法 删除计时、Banner打印、日志打印、异常逻辑后 public ConfigurableApplicationContext run(String... args) {// 对java.awt.headless参数设置[Ignore]this.configureHeadlessProperty();// 使用SPI机制获取SpringApplicationRunListeners// 内部仅包含一个EventPublishingRunListener类型的监听器SpringApplicationRunListeners listeners this.getRunListeners(args);listeners.starting();// 对启动方法的入参进行包装ApplicationArguments applicationArguments new DefaultApplicationArguments(args);// 创建环境变量 [标注1]ConfigurableEnvironment environment this.prepareEnvironment(listeners, applicationArguments);// spring.beaninfo.ignore属性设置[Ignore]this.configureIgnoreBeanInfo(environment);// 根据Servlet类型创建Spring容器 [标注2]ConfigurableApplicationContext context this.createApplicationContext();// 刷新前的预处理 [标注3]this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 刷新容器 标注[4]this.refreshContext(context);// 容器刷新后处理预留扩展接口此时逻辑为空this.afterRefresh(context, applicationArguments);listeners.started(context);// 调用run方法 [标注5]this.callRunners(context, applicationArguments);// 返回AnnotationConfigServletWebServerApplicationContext类型的Spring容器return context;}Note1: 创建环境变量 prepareEnvironment方法用户构造环境变量类型为StandardServletEnvironment包括 [1] systemProperties保存系统属性如java.version, user.name; [2] systemEnvironment保存环境变量如JAVA_HOME, GRADLE_HOME; [3] applicationConfig保存application.yml配置文件信息 … Note2: 创建Spring容器 protected ConfigurableApplicationContext createApplicationContext() { // 省略部分代码 ...switch (this.webApplicationType) {case SERVLET:contextClass Class.forName(org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext);break;case REACTIVE:contextClass Class.forName(org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext);break;default:contextClass Class.forName(org.springframework.context.annotation.AnnotationConfigApplicationContext);}return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass); }webApplicationType为SERVLET类型通过反射构造一个AnnotationConfigServletWebServerApplicationContext类型的对象返回。 Note3: 刷新前的预处理 private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {// 为Spring容器设置环境变量context.setEnvironment(environment);// 对Spring容器的beanNameGenerator(默认启动流程为空)、resourceLoader(默认启动流程为空)、addConversionService组件进行设置postProcessApplicationContext(context);// 调用initializers的initialize方法在new SpringApplication阶段通过SPI获取的ApplicationContextInitializer对象列表applyInitializers(context);listeners.contextPrepared(context);ConfigurableListableBeanFactory beanFactory context.getBeanFactory();// 将启动入参和printedBanner注册到IOC中beanFactory.registerSingleton(springApplicationArguments, applicationArguments);if (printedBanner ! null) {beanFactory.registerSingleton(springBootBanner, printedBanner);}// SpringBoot不支持循环依赖if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}// lazyInitialization为false, 不进行懒加载(LazyInitializationBeanFactoryPostProcessor会将容器中的BeanDefinition的lazyInit属性设置为true从而实现懒加载)if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// 向容器导入主配置类此时为DemoApplication[标注3-1]SetObject sources getAllSources();load(context, sources.toArray(new Object[0]));listeners.contextLoaded(context); }跟踪load方法进入: class BeanDefinitionLoader {// ...private int load(Class? source) {// ...this.annotatedReader.register(source);} } public class AnnotatedBeanDefinitionReader {// ...public void registerBean(Class? beanClass) {doRegisterBean(beanClass, null, null, null, null);} }doRegisterBean方法表示向IOC容器中注册一个beanClass类型的对象此时为DemoApplication. registerBean方法实现逻辑的解读是Spring导入Bean对象的内容本文不进行深究。 Note4: 刷新容器 this.refreshContext(context);内容如下 private void refreshContext(ConfigurableApplicationContext context) {this.refresh((ApplicationContext)context);if (this.registerShutdownHook) {try {context.registerShutdownHook();} catch (AccessControlException var3) {}} }逻辑可以分为两个部分 调用this.refresh((ApplicationContext)context);刷新容器调用context.registerShutdownHook()注册关闭时的勾子函数。context.registerShutdownHook()是通过Runtime.getRuntime().addShutdownHook方法向JVM注册钩子函数在当JVM关闭时执行。 这里需要执行的逻辑包括注销Bean、关闭Bean工厂、清理缓存等。 进入refresh方法 public void refresh() throws BeansException, IllegalStateException { //... 省略部分与主体逻辑无关的代码this.prepareRefresh();ConfigurableListableBeanFactory beanFactory this.obtainFreshBeanFactory();this.prepareBeanFactory(beanFactory);this.postProcessBeanFactory(beanFactory);this.invokeBeanFactoryPostProcessors(beanFactory);this.registerBeanPostProcessors(beanFactory);this.initMessageSource();this.initApplicationEventMulticaster();this.onRefresh();this.registerListeners();this.finishBeanFactoryInitialization(beanFactory);this.finishRefresh(); }上述流程在 Spring系列-1 启动流程 中以及进行介绍过 重复内容这里不进行说明。 此处刷新的Spring容器类型为AnnotationConfigServletWebServerApplicationContext重写了onRefresh方法: protected void onRefresh() {// 空方法super.onRefresh();try {this.createWebServer();} catch (Throwable var2) {throw new ApplicationContextException(Unable to start web server, var2);} }即onRefresh()的核心逻辑在this.createWebServer()方法中该方法用于创建并启动web容器逻辑如下: private void createWebServer() {// this.webServer为nullWebServer webServer this.webServer;// servletContext为nullServletContext servletContext getServletContext();if (webServer null servletContext null) {//获取web容器工厂 [标注4-1]ServletWebServerFactory factory getWebServerFactory();// 构造web容器 [标注4-2]this.webServer factory.getWebServer(getSelfInitializer());// 向IOC注册webServerGracefulShutdown和webServerStartStop对象 [标注4-3]getBeanFactory().registerSingleton(webServerGracefulShutdown,new WebServerGracefulShutdownLifecycle(this.webServer));getBeanFactory().registerSingleton(webServerStartStop,new WebServerStartStopLifecycle(this, this.webServer));} else if (servletContext ! null) {// Ignore...}//占位符替换替换环境变量中名称servletContextInitParams的资源-容器对象initPropertySources(); }Note 4-1getWebServerFactory()用于获取容器工厂 spring-boot-autoconfigure包中定义了ServletWebServerFactoryConfiguration配置类定义了Tomcat、Jetty、Undertow容器工厂配置类: Configuration(proxyBeanMethods false) class ServletWebServerFactoryConfiguration {Configuration(proxyBeanMethods false)ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })ConditionalOnMissingBean(value ServletWebServerFactory.class, search SearchStrategy.CURRENT)static class EmbeddedTomcat {BeanTomcatServletWebServerFactory tomcatServletWebServerFactory(...) {TomcatServletWebServerFactory factory new TomcatServletWebServerFactory();//...return factory;}}Configuration(proxyBeanMethods false)ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })ConditionalOnMissingBean(value ServletWebServerFactory.class, search SearchStrategy.CURRENT)static class EmbeddedJetty {BeanJettyServletWebServerFactory JettyServletWebServerFactory(...) {JettyServletWebServerFactory factory new JettyServletWebServerFactory();//...return factory;}}//... }其中EmbeddedTomcat的注入条件是IOC容器中还没有注入ServletWebServerFactory对象以及类路径中存在Tomcat.class类而Tomcat.class以及Tomcat相关依赖定义在spring-boot-starter-tomcat包中在引入spring-boot-starter-web依赖时会自动引入spring-boot-starter-tomcat依赖即springboot默认使用Tomcat容器。 SpringBoot也可以使用Jetty容器启动pom依赖需要进行调整删除spring-boot-starter-web中引入的tomcat依赖并引入jetty依赖: dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusionsexclusiongroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-tomcat/artifactId/exclusion/exclusions /dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jetty/artifactIdversion2.6.4/version /dependency本文后续以SpringBoot默认的Tomcat为web容器进行介绍。 Note 4-2: this.webServer factory.getWebServer(getSelfInitializer())构造web容器 该步骤包含的内容较多可以拆成两个部分: (1) 参数部分是一个lambda表达式将被作为参数传入到Tomcat类中在Tomcat启动时被调用; (2) 函数部分负责构造并启动web容器。 参数部分: private void selfInitialize(ServletContext servletContext) throws ServletException {// prepareWebApplicationContext用于实现web容器上下文(ApplicationContextFacade类型)与Spring容器相互指向prepareWebApplicationContext(servletContext);// 将servletContext包装成ServletContextScope对象作为Scope对象添加到容器的中以及设置到servletContext的application属性registerApplicationScope(servletContext);WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);for (ServletContextInitializer beans : getServletContextInitializerBeans()) {beans.onStartup(servletContext);}}WebApplicationContextUtils.registerEnvironmentBeans方法将servletContext以servletContext为BeanName注册到IOC中并从servletContext中获取InitParameter和Attribute信息分别以contextParameters和为beanName注册到IOC中。 getServletContextInitializerBeans()方法从IOC中获取ServletContextInitializer、Filter、Servlet对象, 封装为RegistrationBean对象并调用这些对象的onStartup方法。以DispatcherServletRegistrationBean为例进行介绍: public final void onStartup(ServletContext servletContext) throws ServletException {// servlet dispatcherServletString description getDescription();register(description, servletContext);}register(description, servletContext)方法包含两个主要步骤addRegistration和configure:protected ServletRegistration.Dynamic addRegistration(String description, ServletContext servletContext) {// dispatcherServletString name getServletName();// this.servlet就是DispatcherServlet对象将其注册到serverContext容器上下文中return servletContext.addServlet(name, this.servlet);}protected void configure(ServletRegistration.Dynamic registration) {super.configure(registration);String[] urlMapping StringUtils.toStringArray(this.urlMappings);if (urlMapping.length 0 this.alwaysMapUrl) {urlMapping DEFAULT_MAPPINGS;}// 注册urlMapping, 默认是 /if (!ObjectUtils.isEmpty(urlMapping)) {registration.addMapping(urlMapping);}// 设置loadOnStartup, 默认是-1表示懒加载registration.setLoadOnStartup(this.loadOnStartup);if (this.multipartConfig ! null) {registration.setMultipartConfig(this.multipartConfig);}}继续进入factory.getWebServer(getSelfInitializer())方法: public WebServer getWebServer(ServletContextInitializer... initializers) {if (this.disableMBeanRegistry) {Registry.disableRegistry();} // Ignore// 创建Tomcat对象并设置service、connector、engine、Host// 这个Tomcat来自org.apache.catalina.startup包Tomcat tomcat new Tomcat();File baseDir (this.baseDirectory ! null) ? this.baseDirectory : createTempDir(tomcat);tomcat.setBaseDir(baseDir.getAbsolutePath());Connector connector new Connector(this.protocol);connector.setThrowOnFailure(true);tomcat.getService().addConnector(connector);customizeConnector(connector);tomcat.setConnector(connector);tomcat.getHost().setAutoDeploy(false);configureEngine(tomcat.getEngine());for (Connector additionalConnector : this.additionalTomcatConnectors) {tomcat.getService().addConnector(additionalConnector);}// 给Host添加一个Context, 该Context被封装后就是前文提到的web容器上下文// initializers属性被保存在Context中, 在tonmcat启动后调用initializers的onStartUp方法(上文涉及的lambda表达式).prepareContext(tomcat.getHost(), initializers);// 构造、启动并返回web容器[标注3]return getTomcatWebServer(tomcat); }getTomcatWebServer(tomcat)方法逻辑如下 protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {new TomcatWebServer(tomcat, getPort() 0, Shutdown.IMMEDIATE); }其中getPort()得到的端口来源为Spring配置文件, 因此getPort()0; Shutdown.IMMEDIATE为枚举变量。 public TomcatWebServer(Tomcat tomcat, boolean autoStart, Shutdown shutdown) {this.tomcat tomcat;// truethis.autoStart autoStart;// 传入的Shutdown.IMMEDIATE标志立即关闭(而非优雅关闭)因此this.gracefulShutdown设置为nullthis.gracefulShutdown (shutdown Shutdown.GRACEFUL) ? new GracefulShutdown(tomcat) : null;initialize(); }initialize方法中只有两处逻辑需要注意 private void initialize() throws WebServerException {// ... // 启动Tomcatthis.tomcat.start();// ... // 开启一个非守护线程因为Tomcat所有线程为守护线程否则会直接退出进程startDaemonAwaitThread(); }Note 4-3: // 向IOC注册webServerGracefulShutdown和webServerStartStop对象 [标注3] getBeanFactory().registerSingleton(webServerGracefulShutdown,new WebServerGracefulShutdownLifecycle(this.webServer)); getBeanFactory().registerSingleton(webServerStartStop,new WebServerStartStopLifecycle(this, this.webServer));将得到的webServer对象进行包装并注册到IOC中。其中: 可通过WebServerGracefulShutdownLifecycle对象优雅地关闭容器WebServerStartStopLifecycle可以进行容器的启停。优雅关闭指等待所有正在处理的请求完成后再关闭以确保所有连接都被正确地关闭。 Note5: 执行runner的run方法 this.callRunners(context, applicationArguments);逻辑如下 private void callRunners(ApplicationContext context, ApplicationArguments args) {ListObject runners new ArrayList();// 从IOC容器获取所有的ApplicationRunner类型的Bean对象runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());// 从IOC容器获取所有的CommandLineRunner类型的Bean对象runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());// 按照Ordered接口和Order注解进行排序AnnotationAwareOrderComparator.sort(runners);// 按顺序调用ApplicationRunner或CommandLineRunner的run方法 [标注5-1]for (Object runner : runners) {if (runner instanceof ApplicationRunner) {this.callRunner((ApplicationRunner)runner, args);}if (runner instanceof CommandLineRunner) {this.callRunner((CommandLineRunner)runner, args);}} }Note:5-1 调用ApplicationRunner和CommandLineRunner时有try-catch异常保护不会因为某个runner执行异常而影响其他runner执行传入runner的参数就是容器启动时传给SpringApplication的参数即main方法的参数。
http://www.ho-use.cn/article/10822390.html

相关文章:

  • 全球最好的黄页网站app 网站开发
  • 建筑网站设计大全网络营销网站源码
  • 线上海报设计网站番禺区保安服务公司
  • 大连网站制作哪家最好学生个人网页设计主题
  • 网站到期续费通知江门论坛建站模板
  • 北京建设工程质量总站网站如何做贷款网站推广
  • 黑群晖建设个人网站深圳2024新冠最新情况
  • php做数据网站网业端云服务
  • 做汽车团购网站html做的网站图片横着摆放
  • 基于wordpress个人博客网站论文做网站视频用哪个视频编辑软件
  • 上海嘉定网站市场营销八大营销模式
  • 汕头网站专业制作外贸网站是什么意思
  • 义乌网站建设优化排名开个网站卖机器怎么做
  • 网站改版提交技术支持 沧州网站建设
  • 男女做那个的网站是什么找做玻璃的网站
  • 东莞市长安网站建设公司jsp做门户网站
  • 简单的app开发制作南昌网站seo
  • 演出票务网站建设福建住房城乡建设部网站
  • wordpress个人博客网站游戏开发软件工具
  • 杭州网站排名服务全国十大网站设计工作室
  • 山东省建设厅举报网站wordpress安装图片不显示不出来
  • 个人做电梯网站网站建设与发布需要什么
  • 荣县规划和建设局网站官方网站建设成果
  • 沧州市做网站如何免费自学网站建设
  • 包小盒设计网站申请免费网站
  • 网站开发 犯法网站开发费用清单
  • 桂林相关网站扬中论坛最新
  • 网页设计国外设计欣赏网站最赚钱的小型加工厂
  • 深圳做网站公司地点山东省建设工程信息网官网
  • 网站域名缴费高端网站建设 企业网站建站