模拟SpringBoot编写一个嵌套Tomcat的工具类(方便调试)

为了在Spring源码项目中调试SpringMVC代码,使用Tomcat的插件比较方便,那么须要本身模拟编写一个相似SpringBoot的功能:启动Spring应用内嵌Tomcat并作好关联。若是还没构建好一个完整的Spring源码运行环境请参考:Spring5 源码分析--引导片(构建Spring源码运行环境)java

为何要搞这么麻烦喃???由于我是创建的一个普通Java工程,根本web.xml文件,所以须要写代码给Tomcat添加Context\Servlet、与Spring web 上下文绑定。web

要完全弄明白这部分代码,须要对Tomcat和Spring有比较深刻的理解,能够去看看前面的Spring和Tomcat源码分析spring

先在Spring项目中新建一个普通Java工程,注意是用Gradle构建apache

其余步骤省略,只贴出build.gradle文件json

plugins {
    id 'java'
}

group 'org.springframework'
version '5.2.0.BUILD-SNAPSHOT'

sourceCompatibility = 1.8

dependencies {
    compile project(":spring-context")
    compile project(":spring-webmvc")
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '8.5.49'
    compile group: 'org.projectlombok', name: 'lombok', version: '1.18.10'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.8'
}

为何要导入jackson的东西,由于我要将Controller返回的对象转换为json串输出浏览器

上代码:tomcat

模拟Springboot启动自带Tomcat容器mvc

@Configuration
@ComponentScan("com.jv.webmvc")
public class WebMvcMain{
	public static void main(String[] args) {
		try {
			//实例化一个Spring web 上下文
			AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
			ac.register(WebMvcMain.class);
			ac.refresh();

			//实例化Spring的DispatcherServlet DispatcherServlet与上下文绑定
			DispatcherServlet dispatcherServlet = new DispatcherServlet(ac);

			//实例化Tomcat
			Tomcat tomcat = new Tomcat();
			tomcat.setPort(8080);

			//Tomcat添加Servlet
			Context context = tomcat.addContext("/", "f:\\data\\spring-tomcat\\app");
			Tomcat.addServlet(context, "st", dispatcherServlet);
			context.addServletMapping("/", "st");

			//启动Tomcat
			tomcat.start();
			tomcat.getServer().await();
		}catch (Exception e){
			e.printStackTrace();
		}
	}
}

下面这个类是完成HTTPMessageConverter注册(也许有朋友会问为何不用WebMvcConfigure接口重写它的方法完成自定义Converter添加。。。由于我试了不行,我猜想多是由于没用使用@EnableWebMvc)app

@Component
public class MyHttpMessageConverterProcessor implements BeanPostProcessor{
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if(beanName.equals("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter")){
			List<HttpMessageConverter<?>> messageConverters = ((RequestMappingHandlerAdapter) bean).getMessageConverters();
			messageConverters.add(new MappingJackson2HttpMessageConverter());
		}
		return bean;
	}
}

User对象源码分析

@Setter
@Getter
@ToString
public class User {
	public User(){}

	public User(String userName,Integer age){
		this.userName = userName;
		this.age = age;
	}
	private String userName;
	private Integer age;
}

UserController

@RestController
public class UserController {
	private User user = new User("Messi",33);

	@RequestMapping("/user")
	public User queryAllUser(){
		System.out.println(user);
		return user;
	}
}

注意,其余要被扫描到的类必须都在com.jv.webmvc目录及其子目录当中

 

完成上面的代码,启动SpringMVC应用

Tomcat启动成功

浏览器访问:http://localhost:8080/user

下一篇:SpringMVC启动与Spring启动差别分析

相关文章
相关标签/搜索