ディレクトリ
統合されたJSPテンプレートエンジンのSpringBootシリーズ
@
1.はじめにテンプレートエンジン
リファレンステンプレートエンジンBaiduの百科事典は説明しました:
テンプレートエンジンは、(ここでは特にWeb開発テンプレートエンジン用)の分離に起因するユーザーインターフェースとビジネスデータ(コンテンツ)を作ることです、それはウェブサイトのテンプレートエンジンのために、特定の形式の文書を生成することができ、標準を生成します。 HTMLドキュメント。
そこJavaEEの中にいくつかの領域、より一般的に使用されるテンプレートエンジン、つまりJSP、速度、Freemarkerの、Thymeleafが、効率、JSPをレンダリングするためのフロントページのためであるが、それはまだ最速で、ベロシティが続きました。Thymeleaf効率のレンダリング中には非常に高速ではありませんが、文法がよりコンパクトで、ベロシティThymeleaf文法よりも軽いが、速度よりも効率レンダリング
2、環境を準備
[OK]を、Springbootは、などのTomcat、として直接埋め込まれたサーブレットコンテナを実行することができますが、Springbootは、テンプレートエンジンを統合するために、それがされたのJavaEEフレームワーク、非常に簡単なの使用ですが、また、デフォルトのプロジェクトラベル瓶のパッケージを作成し、jarファイルのパッケージを開始しますJSPはデフォルトでサポートされていないが、それは最初にデフォルトジャーによってすべてSpringbootプロジェクト実行の、それを使用することができないという意味ではありません、と私たちの以前のプロジェクト、主に戦争のJSPパケットモードでは、jarファイルは、Webアプリケーションプロジェクトには、デフォルトは存在しないだろうパッケージ化されており、これらのファイルので、我々は、JSPプロジェクトを作成したいので、あなたは戦争にプロジェクトの時間の形でパッケージを作成することができます
OK、行動実験では、JSP、環境が準備します:
- バージョン:
- Maven3.9 +
- SpringBoot2.2.1
- IDE:
- IntelliJ IDEA
Springboot初期化プロジェクトの作成、パッケージは戦争モードを選択します
我々は、手動で追加したり、アイデアで行うことができますので、良いプロジェクトを作成し、デフォルトWebアプリケーションのファイルは、ありません。
新しいweb.xmlが、下のデフォルトのパスを変更することを忘れないで
作成された後、我々は自動的に生成されたプロジェクトの機能が何であるかを見ることができます:
- 最初はやっているもう一つのServletInitializerクラスですか?当時詳細に話します
- Pom文件,翻了一下,发现spring-boot-starter-tomcat的作用范围被改成provided的,这个是什么意思?需要补充一下maven的基础知识,maven中三种classpath 编译,测试,运行
- 1.compile:默认范围,编译测试运行都有效
- 2.provided:在编译和测试时有效
- 3.runtime:在测试和运行时有效
- 4.test:只在测试时有效
5.system:在编译和测试时有效,与本机系统关联,可移植性差
修改scope为provided,也就是在运行时不起效,也就是打成war包时候,就不引入对应的Tomcat jar包,不使用嵌入式的Tomcat容器,使用外部的Tomcat容器
3、外部Servlet容器
Springboot项目创建之后,其实就可以直接创建jsp应用了,然后从其自动生成的配置可以看出我们在创建war包时,是可以使用外部的Tomcat容器的,所以,我们引入一下外部Tomcat
部署时候,直接使用暴露的war即可,Application context可以写上也可以不管
直接创建一个jsp页面
进行页面跳转,写个Controller类:
@Controller
public class HelloController {
@RequestMapping(value = {"/success"})
public String toSuccess(){
return "success";
}
}
注意:还要向以前那样定义一下mvc的一下配置:
spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp
ok,我之前博客SpringBoot源码学习系列之嵌入式Servlet容器已经比较详细地介绍了Springboot嵌入式Servlet容器的知识,所以本博客有必要对比一下嵌入式的Servlet容器和本博客介绍的外部Servlet容器的区别
- 外部Servlet容器:maven打包是war形式,先启动Servlet容器,在创建ioc容器
- 嵌入式Servlet容器:maven打包是jar形式,启动时候先创建ioc容器,再启动嵌入式的Servlet容器,比如Tomcat、undertow等等
4、源码原理简介
シリコンバレーのビデオはまだ戦争のパッケージは自動的に、サーブレットでServletContainerInitializerを導入ServletInitializerクラスを導入し、共有ライブラリとプラグインを実行時、作成時に示すようにセクションを見つけ、文書を下げ、Servlet仕様を導入し、このセクションでは、プロジェクトの作成について説明@HandlesTypes注釈開始時間によって、コンフィギュレーション・ファイルを経由してMETA-INF / servicesに対応するクラスを見つける時間を開始し、コンテナを使用してクラスを初期化するクラスを導入するために必要とされるであろう
春のWebプロジェクトに対応する設定を見つけるためのグローバル検索
@HandlesTypes(WebApplicationInitializer.class)//SpringServletContainerInitializer 容器类启动时候会一起创建WebApplicationInitializer类
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {
List<WebApplicationInitializer> initializers = new LinkedList<>();
if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
//检验WebApplicationInitializer不是一个接口、抽象类就进行实例
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer)
ReflectionUtils.accessibleConstructor(waiClass).newInstance());
}
catch (Throwable ex) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
}
}
}
}
if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
return;
}
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
//遍历获取到的WebApplicationInitializer 类,调用其对应的onStartup方法
for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
}
}
WebApplicationInitializerが実際にインタフェースクラスで、それはあなたがSpringBootServletInitializerクラスを参照することができ、その実装クラスを開設
方法をonStartup実行中に示すようにWebApplicationInitializerインタフェースSpringBootServletInitializerクラスが実装し、キーポイントを見つけるために、サーブレットコンテナの起動時に作成されます。
createRootApplicationContext方法は、コンテナ、ソースを見に応じて作成されます。
protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
//创建SpringApplication的构建器
SpringApplicationBuilder builder = createSpringApplicationBuilder();
builder.main(getClass());//设置main方法
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
if (parent != null) {
this.logger.info("Root context already created (using as parent).");
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
//构建器初始化
builder.initializers(new ParentContextApplicationContextInitializer(parent));
}
builder.initializers(new ServletContextApplicationContextInitializer(servletContext));
builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class);
//关键点,调用configure方法
builder = configure(builder);
builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext));
SpringApplication application = builder.build();
if (application.getAllSources().isEmpty()
&& MergedAnnotations.from(getClass(), SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class)) {
application.addPrimarySources(Collections.singleton(getClass()));
}
Assert.state(!application.getAllSources().isEmpty(),
"No SpringApplication sources have been defined. Either override the "
+ "configure method or add an @Configuration annotation");
// Ensure error pages are registered
if (this.registerErrorPageFilter) {
application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
}
//启动Application类
return run(application);
}
このソースからのキーポイントの設定方法を見つけ、それは、単にコンストラクタを返し、基底クラスのメソッドは非常に単純で、この方法を継続し
、これではありません見て重要な点として、その実現を開くために、CTRL + ALT + Bでのアイデアで、そうServletInitializerクラスが自動的に作成されますか?それがトリガーIoCコンテナのSpringbootの作成を開始する時期と理由をサーブレットコンテナを理解するために今ここに、configureメソッド、およびコンストラクタクラスにSpringboot Applicationクラスを書き換えます
ダウンロードコード例:GitHubのダウンロードリンク