SpringMVC内嵌Tomcat9免web.xml

编程

原理

具体原理可百度嵌入式tomcat,这里就简单介绍一下

在Tomcat8以上版本支持一个配置启动的东西,意思就是tomcat启动时会自动去扫描所有 jar 中目录为「 META-INF/services/ 」中是否有个名字是「javax.servlet.ServletContainerInitializer」的配置文件,然后根据里面内容反编译启动等等一系列操作,具体如下图配置:

如上图配置后tomcat启动时就会自动生成HelloServlet了,大概原理就这样,不过SpringMVC已经把上图中的基本配置已经搞定直接使用即可,具体往下看

普通Maven项目的依赖

<properties>

<spring.version>5.2.3.RELEASE</spring.version>

</properties>

<dependencies>

<dependency>

<groupId>ch.qos.logback</groupId>

<artifactId>logback-classic</artifactId>

<version>1.2.3</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

<version>2.10.2</version>

</dependency>

<dependency>

<groupId>org.apache.tomcat.embed</groupId>

<artifactId>tomcat-embed-core</artifactId>

<version>9.0.30</version>

</dependency>

<dependency>

<groupId>org.apache.tomcat.embed</groupId>

<artifactId>tomcat-embed-jasper</artifactId>

<version>9.0.30</version>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>javax.servlet-api</artifactId>

<version>4.0.1</version>

<scope>provided</scope>

</dependency>

</dependencies>

主要SpringMVC配置

Spring官网:https://docs.spring.io/spring/docs/5.0.14.RELEASE/spring-framework-reference/web.html#spring-web

代码中的 app.xml 是普通Spring项目的配置,关于SpringMVC配置就代码中已加入的注解式配置

public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

// 返回Spring应用根容器中定义的beans,对应ContextLoaderListener,是Spring根容器

protected Class<?>[] getRootConfigClasses() {

return new Class<?>[]{RootConfig.class};

}

//protected Class<?>[] getRootConfigClasses() {

// return new Class[0];

//}

// 返回Spring MVC应用容器中定义的beans,对应DispatcherServlet中加载的bean

// Spring MVC容器是根容器的子容器,子容器可以看到根容器中定义的beans,反之不行

protected Class<?>[] getServletConfigClasses() {

return new Class<?>[]{ServletConfig.class};

}

// 指定映射拦截URL

protected String[] getServletMappings() {

return new String[]{"/"};

}

// 修改 通过重写此方法修改DispatcherServlet的名称,对应<servlet-name></servlet-name>标签

@Override

protected String getServletName() {

return super.getServletName();

}

@Override

protected Filter[] getServletFilters() {

return new Filter[]{new SimpleFilter()};

}

}

@Configuration

@ImportResource(locations = "classpath:config/app.xml")

public class RootConfig {

private final Logger logger = LoggerFactory.getLogger(RootConfig.class);

@Bean

public ApplicationContextAware applicationContextAware(ApplicationContext ctx) {

return args -> {

/**

System.err.println("beans:");

String[] beanNames = ctx.getBeanDefinitionNames();

//Arrays.sort(beanNames);

for (String beanName : beanNames) {

System.err.println("---> " + beanName);

}

*/

System.out.println("Beans: " + ctx.getBeanDefinitionCount());

logger.info("==========- 启动完成 -==========");

};

}

}

@Configuration

@EnableWebMvc //@EnableWebMvc 同等 WebMvcConfigurationSupport

@ComponentScan("com.*.*.web.controller")

public class ServletConfig {

@Bean

public ViewResolver viewResolver() { // 配置 视图解析器

InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

viewResolver.setPrefix("/WEB-INF");

viewResolver.setSuffix(".jsp");

viewResolver.setExposeContextBeansAsAttributes(true);

//viewResolver.setOrder(0);

//viewResolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);

return viewResolver;

}

}

 

Tomcat启动代码

package com.fourlambs.proxyip;

import org.apache.catalina.Context;

import org.apache.catalina.connector.Connector;

import org.apache.catalina.startup.Tomcat;

import org.apache.tomcat.util.descriptor.web.ErrorPage;

import java.io.File;

import java.io.IOException;

import java.net.ServerSocket;

/**

* @Author yuwan [2020-02-07]

* @Date February, 07, Friday

* @Comment ...

*/

public class AppMain {

static void testPort(int port) throws IOException {

// 检测端口是否被占用

ServerSocket socket = null;

try {

socket = new ServerSocket(port);

} catch (IOException e) {

System.err.println(port + " 端口已被占用");

System.exit(0);

return;

} finally {

socket.close();

}

}

public static void main(String[] args) {

int port = 8080;

try {

if (args.length > 0) {

port = Integer.parseInt(args[0]);

}

testPort(port);

// Windows系统上运行必须要有webapps文件夹,不然启动不了,辣鸡!

String osName = System.getProperties().getProperty("os.name");

if (osName.toLowerCase().contains("windows")) {

String path = AppMain.class.getResource("/").getPath() + "/webapps";

File file = new File(path);

if (!file.exists()) {

file.mkdir();

}

}

Tomcat tomcat = new Tomcat();

//System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");

String baseDir = Thread.currentThread().getContextClassLoader().getResource("").getPath();

tomcat.setBaseDir(baseDir);

tomcat.setPort(port);

Context ctx = tomcat.addWebapp("", baseDir);

ctx.setParentClassLoader(Thread.currentThread().getContextClassLoader());

//ctx.setLoader(new WebappLoader(Thread.currentThread().getContextClassLoader()));

ctx.setRequestCharacterEncoding("UTF-8");

ErrorPage ep = new ErrorPage();

//ep.setErrorCode(404);

ep.setLocation("/error");

ctx.addErrorPage(ep);

// 特殊资源

//StandardRoot resources = new StandardRoot(ctx);

//WebResourceSet resourceSet = new EmptyResourceSet(resources);

//WebResourceSet resourceSet = new DirResourceSet(resources, "/", "/", "/");

//resources.addPreResources(resourceSet);

//ctx.setResources(resources);

Connector connector = tomcat.getConnector();

connector.setAttribute("maxThreads", 500);

//connector.setAttribute("minSpareThreads", 2);

//tomcat.enableNaming();

tomcat.start();

tomcat.getServer().await();

} catch (Exception e) {

System.err.println("启动错误 Error:" + e.getMessage());

System.err.println("命令启动时第一个参数为端口号(默认端口" + port + ")");

e.printStackTrace();

}

}

}

 

Tomcat简单嵌入重中之重就是上面的tomcat启动代码。。。。难点是官网没有文档,憋来没办法去研究源码。。。阿帕奇是个大坑比!!

重点代码已列出来了,仅供学习参考!高级的tomcat配置及使用建议最好还是老老实实下载tomcat来运行和配置

 

 

 

 

以上是 SpringMVC内嵌Tomcat9免web.xml 的全部内容, 来源链接: utcz.com/z/514252.html

回到顶部