springMvc整合undertow容器
因为项目要求用springMvc,但是默认以war包发布到tomact下每一次启动都会很慢,所以希望能用一个嵌入式的web容器,了解到undertow对于小型项目还不错,就使用了undertow.最开始用的Jfinal-undertow,但是突然看到出了spring6.0,就想体验一下,spring6.0对应的servlet版本比较高,jfinal-undertow并不兼容,所以就自己找到了undertow进行使用,以下就是折腾的经历。
1. 依赖安装
<!-- https://mvnrepository.com/artifact/io.undertow/undertow-servlet -->
<dependency><groupId>io.undertow</groupId><artifactId>undertow-servlet</artifactId><version>2.3.3.Final</version>
</dependency><!-- https://mvnrepository.com/artifact/io.undertow/undertow-core -->
<dependency><groupId>io.undertow</groupId><artifactId>undertow-core</artifactId><version>2.3.3.Final</version>
</dependency>
在项目原本的依赖下加入以上两个依赖,版本需要对应一样,分别是undertow的核心依赖和undertow的servlet相关实现。
2. 运行整合
2.1 添加servlet
// 创建servletInfo,指定servlet的命名和servlet对应的class
ServletInfo info = new ServletInfo("mvc", DispatcherServlet.class)// 添加映射路径.addMapping("/")// 设置InitParam,制定了spring-mvc的配置文件位置.addInitParam("contextConfigLocation","classpath:spring-config/spring-mvc.xml")// 设置什么时候进行初始化.setLoadOnStartup(1);
2.2 创建容器
undertow的一个web容器就是一个DeploymentManager,该接口的默认实现类就是DeploymentManagerImpl,然后需要两个参数,分别是DeploymentInfo和ServletContainer,所以需要先创建DeploymentInfo,然后创建ServletContainer,因为ServletContainer也需要DeploymentInfo作为参数,代码如下所示。
// 创建DeploymentInfo 对象
DeploymentInfo deploymentInfo = new DeploymentInfo()// 指定类加载器.setClassLoader(TestServer.class.getClassLoader())// 设置contextPath.setContextPath("/")// 设置容器名称.setDeploymentName("myUndertow")// 设置初始化参数,制定了spring的配置文件的位置.addInitParameter("contextConfigLocation","classpath:spring-config/spring.xml")// 设置了一个监听器,用于初始化spring.addListener(new ListenerInfo(ContextLoaderListener.class))// 添加servlet.addServlet(info)// 添加一个过滤器,放置乱码问题.addFilter(new FilterInfo("Encoding", CharacterEncodingFilter.class).addInitParam("encoding","utf-8"));// 创建一个ServletContainer,并添加deploymentInfoServletContainerImpl container = new ServletContainerImpl();container.addDeployment(deploymentInfo);// 创建一个DeploymentManagerImplDeploymentManagerImpl manager = new DeploymentManagerImpl(deploymentInfo, container);// 部署该容器,一定要部署否则会报各种空指针manager.deploy();```## 2.3 添加HttpHandler因为是web项目,所以使用HttpHandler,HttpHandler默认有很多实现类,这里使用了最好理解的**PathHandler**,创建完之后添加到**Undertow**的Builder参数中,作为一个Listener,然后启动Undertow。```java
// 创建一个PathHandler,然后添加一个前缀匹配,DeploymentManagerImpl 调用start方法后会返回一个HttpHandler类型
PathHandler root = new PathHandler().addPrefixPath(deploymentInfo.getContextPath(), manager.start());
// 创建一个Undertow对象并配置启动的端口等参数,然后调用start方法启动
Undertow.Builder builder = Undertow.builder().addHttpListener(port, host, root);
Undertow undertow = builder.build();
undertow.start();
logger.info(" the undertow success listen http://"+host+":"+port);
2.4 读取配置文件
我也希望向springBoot项目一样可以直接读取端口等参数直接启动,但是因为容器运行时spring容器还没有运行,所以我才用的方法是手动读取文件并注入字段。
public void initConfig(String configPath) throws IllegalAccessException {if (configPath.equals("")){configPath = "config/application.yml";}// 读取yaml文件并转换为proppertiesYamlPropertiesFactoryBean propertiesFactoryBean = new YamlPropertiesFactoryBean();propertiesFactoryBean.setResources(new ClassPathResource(configPath));// 配置log4j基本信息PropertyConfigurator.configure(propertiesFactoryBean.getObject());// 读取当前类的字段Field[] fields = this.getClass().getDeclaredFields();for (Field field:fields) {// 检查是否包含Value注解if (field.getAnnotation(Value.class) != null) {String value = field.getAnnotation(Value.class).value();value = value.substring(2).substring(0, value.length() - 3);// 注入参数field.set(this,propertiesFactoryBean.getObject().get(value));}}}@Value("${server.host}")public String host;@Value("${server.port}")public Integer port;
3. 最后
完整代码如下
package org.gjs;import io.undertow.Undertow;import io.undertow.server.handlers.PathHandler;import io.undertow.servlet.UndertowServletMessages;import io.undertow.servlet.api.DeploymentInfo;import io.undertow.servlet.api.FilterInfo;import io.undertow.servlet.api.ListenerInfo;import io.undertow.servlet.api.ServletInfo;import io.undertow.servlet.core.DeploymentImpl;import io.undertow.servlet.core.DeploymentManagerImpl;import io.undertow.servlet.core.ManagedServlet;import io.undertow.servlet.core.ServletContainerImpl;import io.undertow.servlet.handlers.ServletHandler;import io.undertow.servlet.handlers.ServletInitialHandler;import io.undertow.servlet.handlers.ServletPathMatches;import io.undertow.servlet.spec.ServletContextImpl;import jakarta.servlet.ServletException;import org.apache.log4j.Logger;import org.apache.log4j.PropertyConfigurator;import org.gjs.config.MyUndertowConfig;import org.springframework.beans.factory.annotation.Value;import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;import org.springframework.core.io.ClassPathResource;import org.springframework.http.server.reactive.UndertowHttpHandlerAdapter;import org.springframework.web.context.ContextLoaderListener;import org.springframework.web.filter.CharacterEncodingFilter;import org.springframework.web.servlet.DispatcherServlet;import java.lang.reflect.Field;public class TestServer {private final Logger logger = Logger.getLogger(this.getClass());public static void main(String[] args) throws ServletException, IllegalAccessException {TestServer server = new TestServer();server.initConfig("");server.start();}public void initConfig(String configPath) throws IllegalAccessException {if (configPath.equals("")){configPath = "config/application.yml";}YamlPropertiesFactoryBean propertiesFactoryBean = new YamlPropertiesFactoryBean();propertiesFactoryBean.setResources(new ClassPathResource(configPath));// 配置log4j基本信息PropertyConfigurator.configure(propertiesFactoryBean.getObject());Field[] fields = this.getClass().getDeclaredFields();for (Field field:fields) {if (field.getAnnotation(Value.class) != null) {String value = field.getAnnotation(Value.class).value();value = value.substring(2).substring(0, value.length() - 3);field.set(this,propertiesFactoryBean.getObject().get(value));}}}@Value("${server.host}")public String host;@Value("${server.port}")public Integer port;public void start() throws ServletException {ServletInfo info = new ServletInfo("mvc", DispatcherServlet.class).addMapping("/").addInitParam("contextConfigLocation","classpath:spring-config/spring-mvc.xml").setLoadOnStartup(1);DeploymentInfo deploymentInfo = new DeploymentInfo().setClassLoader(TestServer.class.getClassLoader()).setContextPath("/").setDeploymentName("myUndertow").addInitParameter("contextConfigLocation","classpath:spring-config/spring.xml").addListener(new ListenerInfo(ContextLoaderListener.class)).addServlet(info).addFilter(new FilterInfo("Encoding", CharacterEncodingFilter.class).addInitParam("encoding","utf-8"));ServletContainerImpl container = new ServletContainerImpl();container.addDeployment(deploymentInfo);DeploymentManagerImpl manager = new DeploymentManagerImpl(deploymentInfo, container);manager.deploy();PathHandler root = new PathHandler().addPrefixPath(deploymentInfo.getContextPath(), manager.start());Undertow.Builder builder = Undertow.builder().addHttpListener(port, host, root);Undertow undertow = builder.build();undertow.start();logger.info(" the undertow success listen http://"+host+":"+port);}}
springMvc整合undertow容器相关推荐
- 六:Dubbo与Zookeeper、SpringMvc整合和使用
DUBBO与ZOOKEEPER.SPRINGMVC整合和使用 互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架 ...
- 【转】Dubbo_与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
原文链接:http://blog.csdn.net/congcong68/article/details/41113239 互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服 ...
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)(转)
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
- 实战_02_Spring SpringMVC 整合Mybaits
接上一篇:企业实战_01_Spring SpringMVC 整合Mybaits https://blog.csdn.net/weixin_40816738/article/details/101343 ...
- SpringMVC(2)—SpringMVC整合Spring的HelloWorld
一.这是一个SpringMVC框架的案例HelloWorld 功能:HelloWorld 二.SpringMVC运行流程 1.流程 请求-->springDispatcherServlet的ur ...
- 【JEECG dubbo专题】Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
- 转:Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
Dubbo与Zookeeper.SpringMVC整合和使用(负载均衡.容错) 标签: Dubbospringmvczookeeper负载均衡 2014-11-14 08:14 83517人阅读 评论 ...
- Spring和SpringMVC整合
Spring和SpringMVC整合出现的问题: 原因 SpringMVC就运行在Spring环境之下,为什么还要整合呢?SpringMVC和Spring都有IOC容器,是不是都需要保留呢? 通常情况 ...
- 160906、Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
最新文章
- R语言广义线性模型泊松回归(Poisson Regression)模型
- 解决报错:Can't read private key和./build-aux/cksum-schema-check: Permission denied
- IBM copy service--flashcopy 实验
- 步入三十岁前的总结:看似经历很多得到很多,但,实际却一无所得
- Django - 两周从入门到熟练工
- 超越java jb51_.net mvc超过了最大请求长度的解决方法
- 浙江大学 计算机学院 秦青青,我院研究生在乒乓球大赛中喜获佳绩
- 使用FFTW的fftw_plan_dft_c2r_1d()由于未归一化结果错误的解决方案
- 解决在极光推送的时候会出现一个 JPush提示:缺少统计代码
- Dirichlet分布深入理解
- 5、maplotlib中的轴刻度和轴线
- maven内存不足:Unexpected error occurred: Not enough memory to allocate buffers for rehashing Java heap
- 使用Altium Designer绘制电路原理图
- MATLAB-二次曲面
- 概率论:古典概型与伯努利概型
- Android仿微信图片编辑处理:文字,马赛克,裁剪,涂鸦,旋转图片等
- 现代网络负载均衡和代理技术
- js之浏览器本地存储webstorage
- 【Typora Emoji 图标】
- 数控车椭圆编程实例带图_数控车床加工椭圆的宏程序实例
热门文章
- 毛星云opencv之ROI图像叠加混合--5.2.1(定义ROI区域的方法)
- Hive sql 行转列
- 数据结构——冒泡算法
- 对不起, 老师 我把知识还给您了 呜呜呜 ......面试杀手-double精度问题深入剖析 进制转换
- Unity源码3||秀翻同学和老师
- 教育部 计算机类专业代码,科普下2020教育部703个本科专业目录及专业代码
- 免费的SSL证书(Let‘s Encrypt / acme)
- html,jsp和js的区别
- android手势解锁说明
- Springboot 2.0默认连接池HikariCP详解(效率最高)