模擬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啓動差別分析

相關文章
相關標籤/搜索