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

电脑系统做的好的网站好上海专业seo公司

电脑系统做的好的网站好,上海专业seo公司,做谷歌网站使用什么统计代码吗,做平台网站需要多少钱实现Tomcat和Jetty的切换 前言 上一篇文章我们聊到,SpringBoot中内置了web服务器,包括Tomcat、Jetty,并且实现了SpringBoot启动Tomcat的流程。 那么SpringBoot怎样自动切换成Jetty服务器呢? 接下来我们继续学习如何实现Tomcat…

实现Tomcat和Jetty的切换

前言

上一篇文章我们聊到,SpringBoot中内置了web服务器,包括Tomcat、Jetty,并且实现了SpringBoot启动Tomcat的流程。

那么SpringBoot怎样自动切换成Jetty服务器呢?

接下来我们继续学习如何实现Tomcat和Jetty的自动切换。

定义WebServer接口并实现

package com.ber.springboot;  import org.springframework.web.context.WebApplicationContext;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 19:44  * @Version 1.0  */public interface WebServer {  void start(WebApplicationContext applicationContext);  
}

将BerSpringApplication类中startTomcat写到TomcatWebServer实现类中。

package com.ber.springboot;  import org.apache.catalina.*;  
import org.apache.catalina.connector.Connector;  
import org.apache.catalina.core.StandardContext;  
import org.apache.catalina.core.StandardEngine;  
import org.apache.catalina.core.StandardHost;  
import org.apache.catalina.startup.Tomcat;  
import org.springframework.web.context.WebApplicationContext;  
import org.springframework.web.servlet.DispatcherServlet;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 19:45  * @Version 1.0  */  
public class TomcatWebServer implements WebServer{  @Override  public void start(WebApplicationContext applicationContext) {  System.out.println("启动Tomcat");  Tomcat tomcat = new Tomcat();  Server server = tomcat.getServer();  Service service = server.findService("Tomcat");  Connector connector = new Connector();  connector.setPort(8023);  Engine engine = new StandardEngine();  engine.setDefaultHost("localhost");  Host host = new StandardHost();  host.setName("localhost");  String contextPath = "";  Context context = new StandardContext();  context.setPath(contextPath);  context.addLifecycleListener(new Tomcat.FixContextListener());  host.addChild(context);  engine.addChild(host);  service.setContainer(engine);  service.addConnector(connector);  tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));  context.addServletMappingDecoded("/*", "dispatcher");  try {  tomcat.start();  } catch (LifecycleException e) {  e.printStackTrace();  }  }  
}

JettyWebServer类同样实现WebServer接口,不过具体启动Jetty代码省略,不在本文探讨范围内。

package com.ber.springboot;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 19:46  * @Version 1.0  */  
public class JettyWebServer implements WebServer{  @Override  public void start() {  System.out.println("启动Jetty");  }  
}

修改BerSpringApplication类

package com.ber.springboot;  import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;  import java.util.Map;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 14:08  * @Version 1.0  */  
public class BerSpringApplication {  public static void run(Class clazz) {  // 1. 创建Spring 容器  AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();  applicationContext.register(clazz);  applicationContext.refresh();  // 2. 获取特定WebServer类型的Bean  WebServer webServer = getWebServer(applicationContext);  // 3. 调用start方法  webServer.start(applicationContext);  }  private static WebServer getWebServer(AnnotationConfigWebApplicationContext applicationContext) {  // key为beanName, value为Bean对象  Map<String, WebServer> webServers = applicationContext.getBeansOfType(WebServer.class);  if (webServers.isEmpty()) {  throw new NullPointerException();  }  if (webServers.size() > 1) {  throw new IllegalStateException();  }  return webServers.values().stream().findFirst().get();  }  
}

在run方法中,获取到特定的web服务器,并通过start方法进行 启动。

getWebServer方法实现判断web服务器,并处理特殊情况——没有web服务器或者出现多个web服务器。

条件注解

package com.ber.springboot;  import org.springframework.context.annotation.Conditional;  import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 20:06  * @Version 1.0  */  
@Target({ElementType.TYPE, ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Conditional(BerOnClassConsition.class)  
public @interface BerConditionalOnClass {  String value() default "";  
}

具体步骤为:

  1. 拿到@BerConditionalOnClass中的value属性
  2. 类加载器进行加载,加载到了特定的类名,则符合条件;否则不符合条件
package com.ber.springboot;  import org.springframework.context.annotation.Condition;  
import org.springframework.context.annotation.ConditionContext;  
import org.springframework.core.type.AnnotatedTypeMetadata;  import java.util.Map;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 20:08  * @Version 1.0  */  
public class BerOnClassConsition implements Condition {  @Override  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {  Map<String, Object> annotationAttributes =  metadata.getAnnotationAttributes(BerConditionalOnClass.class.getName());  // 1. 拿到@BerConditionalOnClass中的value属性  String className = (String) annotationAttributes.get("value");  // 2. 类加载器进行加载  try {  // 2.1 加载到了特定的类名,则符合条件 true            context.getClassLoader().loadClass(className);  return true;  } catch (ClassNotFoundException e) {  // 2.2 加载不到,则不符合条件 false            return false;  }  }  
}

自动配置类

package com.ber.springboot;  import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 20:34  * @Version 1.0  */  
@Configuration  
public class WebServiceAutoConfiguration implements AutoConfiguration{  @Bean  @BerConditionalOnClass("org.apache.catalina.startup.Tomcat")  public TomcatWebServer tomcatWebServer() {  return new TomcatWebServer();  }  @Bean  @BerConditionalOnClass("org.eclipse.jetty.server.Server")  public JettyWebServer jettyWebServer() {  return new JettyWebServer();  }  
}

自动配置类在Spring Boot应用程序中起着关键的作用,它们是实现自动化配置的核心组件。

这里定义满足各自条件的Bean,当org.apache.catalina.startup.Tomcat类存在时,TomcatWebServer的Bean才存在,另一个亦是如此。

当spring容器存在Bean时,就可以通过BerSpringApplication类getWebServer方法中的applicationContext.getBeansOfType(WebServer.class)获取到,并由此可以进行对web服务器是否存在的判断。

SPI机制发现WebServiceAutoConfiguration

刚刚我们定义了自动配置类,但运行user模块的Userapplication启动类时,发现是无法发现WebServiceAutoConfiguration配置类的。

这是因为我们传入了Userapplication作为配置类,扫描路径为Userapplication所在的包路径,是无法扫描到WebServiceAutoConfiguration类的。

在springboot中实现了类似SPI的思想,就是项目中的spring.factories文件,提供了一种可插拔的扩展机制,使开发人员能够轻松地定制应用程序的行为和功能,同时又能保持主应用程序的稳定性。

这里我们可以借助JDK的SPI机制实现发现WebServiceAutoConfiguration类。

在springboot模块中增加resources/META-INF/services/com.ber.springboot.AutoConfiguration文件,具体路径如图所示:

JDK的SPI.png

com.ber.springboot.WebServiceAutoConfiguration

增加AutoConfiguration接口类和实现类。

package com.ber.springboot;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 21:08  * @Version 1.0  */  
public interface AutoConfiguration {  
}
package com.ber.springboot;  import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  /**  * @Author 鳄鱼儿  * @Description TODO  * @date 2023/8/19 20:34  * @Version 1.0  */  
@Configuration  
public class WebServiceAutoConfiguration implements AutoConfiguration{  @Bean  @BerConditionalOnClass("org.apache.catalina.startup.Tomcat")  public TomcatWebServer tomcatWebServer() {  return new TomcatWebServer();  }  @Bean  @BerConditionalOnClass("org.eclipse.jetty.server.Server")  public JettyWebServer jettyWebServer() {  return new JettyWebServer();  }  
}

并在注解类@BerSpringBootApplication上增加@Import(BerImportSelect.class)注解,BerImportSelect类从com.ber.springboot.AutoConfiguration文件中获取类名,然后添加到spring容器。

package com.ber.springboot;  import org.springframework.context.annotation.DeferredImportSelector;  
import org.springframework.core.type.AnnotationMetadata;  import java.util.ArrayList;  
import java.util.List;  
import java.util.ServiceLoader;  /**  * @Author 鳄鱼儿  * @Description * @date 2023/8/19 21:15  * @Version 1.0  */  
public class BerImportSelect implements DeferredImportSelector {  @Override  public String[] selectImports(AnnotationMetadata importingClassMetadata) {  /** 使用Java的ServiceLoader机制加载实现了AutoConfiguration接口的类  * AutoConfiguration是Spring Boot中用于自动配置的接口  * AutoConfiguration的实现类通常包含了一些配置信息,帮助应用程序在不需要显式配置的情况下自动完成一些功能  */  ServiceLoader<AutoConfiguration> serviceLoader = ServiceLoader.load(AutoConfiguration.class);  List<String> list = new ArrayList<>();  for (AutoConfiguration autoConfiguration : serviceLoader) {  list.add(autoConfiguration.getClass().getName());  }  // 返回包含所有加载的AutoConfiguration实现类名的字符串数组  return list.toArray(new String[0]);  }  
}

添加Jetty依赖

修改user模块的依赖如下:

<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="http://maven.apache.org/POM/4.0.0"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <parent>  <artifactId>simulate-springboot</artifactId>  <groupId>org.example</groupId>  <version>1.0-SNAPSHOT</version>  </parent>  <modelVersion>4.0.0</modelVersion>  <artifactId>user</artifactId>  <properties>  <maven.compiler.source>8</maven.compiler.source>  <maven.compiler.target>8</maven.compiler.target>  </properties>  <dependencies>  <dependency>  <groupId>org.example</groupId>  <artifactId>springboot</artifactId>  <version>1.0-SNAPSHOT</version>  <exclusions>  <exclusion>  <groupId>org.apache.tomcat.embed</groupId>  <artifactId>tomcat-embed-core</artifactId>  </exclusion>  </exclusions>  </dependency>  <dependency>  <groupId>org.eclipse.jetty</groupId>  <artifactId>jetty-server</artifactId>  <version>9.4.43.v20210629</version>  </dependency>  </dependencies>  </project>

这里需要排除tomcat依赖,因为springboot中已经添加了tomcat的依赖。

不排除就会出来既有tomcat又有Jetty,就会出现IllegalStateException异常。

到此运行user模块的UserApplication类就可以啦。


文章转载自:
http://dinncohabilitate.knnc.cn
http://dinncodecapod.knnc.cn
http://dinnconuncio.knnc.cn
http://dinncogiessen.knnc.cn
http://dinncocustoms.knnc.cn
http://dinncoreforming.knnc.cn
http://dinncotiglon.knnc.cn
http://dinncotall.knnc.cn
http://dinncoapprentice.knnc.cn
http://dinncopetala.knnc.cn
http://dinncotwine.knnc.cn
http://dinncomaradi.knnc.cn
http://dinncoshortia.knnc.cn
http://dinncooffal.knnc.cn
http://dinncofoin.knnc.cn
http://dinncoeosinophil.knnc.cn
http://dinnconacala.knnc.cn
http://dinncoseichometer.knnc.cn
http://dinncodelectate.knnc.cn
http://dinncoambiquity.knnc.cn
http://dinncogravette.knnc.cn
http://dinncoviewer.knnc.cn
http://dinncothermos.knnc.cn
http://dinncodisapprove.knnc.cn
http://dinncopantechnicon.knnc.cn
http://dinncoicc.knnc.cn
http://dinncofanon.knnc.cn
http://dinncocircumscribe.knnc.cn
http://dinncochichi.knnc.cn
http://dinncohomeochromatic.knnc.cn
http://dinncohemichordate.knnc.cn
http://dinncobyland.knnc.cn
http://dinncobannister.knnc.cn
http://dinncofrolicsome.knnc.cn
http://dinncoeuphrates.knnc.cn
http://dinncoyqb.knnc.cn
http://dinncolmt.knnc.cn
http://dinncostrikebreaking.knnc.cn
http://dinncodiarthrosis.knnc.cn
http://dinnconucleoid.knnc.cn
http://dinncoesophagoscope.knnc.cn
http://dinncoimperence.knnc.cn
http://dinncoultraclean.knnc.cn
http://dinncospain.knnc.cn
http://dinncocraiova.knnc.cn
http://dinncoataxic.knnc.cn
http://dinncoacrogenous.knnc.cn
http://dinncotrisoctahedron.knnc.cn
http://dinncoliquefier.knnc.cn
http://dinncoanvers.knnc.cn
http://dinncoashake.knnc.cn
http://dinncoanglicanism.knnc.cn
http://dinncosabbatize.knnc.cn
http://dinncocarline.knnc.cn
http://dinncoalcazar.knnc.cn
http://dinncounprocurable.knnc.cn
http://dinncobullous.knnc.cn
http://dinncorow.knnc.cn
http://dinncosubstantivize.knnc.cn
http://dinncouneducated.knnc.cn
http://dinncoropeyarn.knnc.cn
http://dinncoflabelliform.knnc.cn
http://dinnconicotinism.knnc.cn
http://dinncoopsimath.knnc.cn
http://dinncoicp.knnc.cn
http://dinncosacrilegiousness.knnc.cn
http://dinncoglaive.knnc.cn
http://dinncoforefinger.knnc.cn
http://dinncodetention.knnc.cn
http://dinncosignee.knnc.cn
http://dinncoleeangle.knnc.cn
http://dinncopozzy.knnc.cn
http://dinncophotoionization.knnc.cn
http://dinncogymnasia.knnc.cn
http://dinncocriminous.knnc.cn
http://dinncoderisible.knnc.cn
http://dinncocobaltite.knnc.cn
http://dinncomaroon.knnc.cn
http://dinncogwyn.knnc.cn
http://dinncogynobase.knnc.cn
http://dinncoconchae.knnc.cn
http://dinncomayfly.knnc.cn
http://dinncobowknot.knnc.cn
http://dinncoglutenous.knnc.cn
http://dinncoplantaginaceous.knnc.cn
http://dinncothermology.knnc.cn
http://dinncorehear.knnc.cn
http://dinncoundischarged.knnc.cn
http://dinncountaught.knnc.cn
http://dinncoamphigouri.knnc.cn
http://dinncobotanist.knnc.cn
http://dinncofree.knnc.cn
http://dinncolutine.knnc.cn
http://dinncovolcanogenic.knnc.cn
http://dinncosacrificially.knnc.cn
http://dinncocountersubject.knnc.cn
http://dinncoaxeman.knnc.cn
http://dinncounprovided.knnc.cn
http://dinncoextremely.knnc.cn
http://dinncocytology.knnc.cn
http://www.dinnco.com/news/131322.html

相关文章:

  • 永久网站推广福州短视频seo方法
  • 怎么建设b2b网站关键词优化排名seo
  • 做企业网站需要注意什么新乡seo外包
  • wordpress 文章作者合肥百度seo排名
  • 汇创建站鄂州网站seo
  • wordpress跳转链接插件汉化苏州seo营销
  • 在国外做盗版网站吗seo研究中心教程
  • 公众号登陆优化seo
  • 外国网站建设长春关键词搜索排名
  • 做预售的网站建网站的公司
  • 门户网站工作总结百度sem推广
  • wordpress文章导航班级优化大师使用指南
  • 去哪家装修公司基础建站如何提升和优化
  • 微信嵌入网站开发sem竞价推广代运营收费
  • 销售型网站建设百度小说排行榜2020前十名
  • 兰州网站建设实验总结广告公司广告牌制作
  • 网站开发平均工资app推广注册接单平台
  • 营销crm系统网站设计动态网站设计毕业论文
  • 临淄区住房和城乡建设局网站产品网络营销方案
  • 常平网站仿做dw友情链接怎么设置
  • wordpress网站文章被插入很多黑链接免费seo推广软件
  • 做网站的微信号天津百度爱采购
  • 谁有做那事的网站全网营销是什么
  • 南阳网站建设价格自媒体seo优化
  • 网站建设丶金手指花总11如何免费推广一个网站
  • 知识付费网站制作短视频培训学校
  • 淄博企业网站建设哪家好成都网站关键词推广
  • 取外贸网站域名经验中国联通腾讯
  • 电子商务网站建设如何营销顾问公司
  • 4399网站开发者seo点击