Simple Web applications are often built in the usual work and learning. If only HelloWorld level of the program, using the traditional SPRING+SPRINGMVC framework to build a word will spend most of the time on the framework itself, such as the introduction of SPRINGMVC, configuration Dispatcheherservlet and so on. And these profiles are pretty much the same, and repeating the work seems a little pointless. So it's very convenient and efficient to use the Springboot framework to build simple applications.
The first two days of work require a simple Web program for testing file downloads, provided the use of Tomcat Docker image is used as a vector, so the springboot framework is quickly built for convenience.
The program writes out to be able to run normally in this machine, prepares to make the mirror, but the smell question is incoming. The first is the issue of deployment, Springboot Web program is the default to hit the jar package, the runtime using the command java-jar-xms128m-xmx128m Xxx.jar, the machine run no problem. But the requirement is to use an external tomcat container instead of tomcat-embed, so check the official documentation as follows:
The first step in producing a deployable war file was to provide a springbootservletinitializer subclass and override its C Onfigure method. Doing so makes use of the Spring Framework ' s Servlet 3.0 support and lets you configure your application when it's launched B Y the servlet container. Typically, you should update your application ' s main class to extend Springbootservletinitializer, as shown in the Followi ng Example:
@SpringBootApplication
public class application extends Springbootservletinitializer {br/> @Override
Return application.sources (Application.class);
}
public static void Main (string[] args) throws Exception {
Springapplication.run (Application.class, args);
}
}
The next step is to update your build configuration Such this your project produces a war file rather than a jar file. If you use Maven and Spring-boot-starter-parent (which configures Maven's war plugin for your), all your need to do are to MoD Ify Pom.xml to change the packaging to war, as follows:
<packaging>war</packaging>
If You use Gradle, you need to modify Build.gradle to apply the war plugin to the project, as follows:
Apply plugin: ' War '
The final step in the process was to ensure, the embedded servlet container does not interfere with the servlet contain Er to which the war file is deployed. To does so, you need to mark the embedded Servlet container dependency as being provided.
If You use Maven, the following example marks the servlet container (Tomcat, in this case) as being provided:
<dependencies>
org.springframework.boot spring-boot-starter-tomcat provided If You use Gradle, the following example marks the servlet container (Tomcat, in this case) as being provided:dependencies {//... providedruntime ' org.springframework.boot:spring-boot-starter-tomcat '//...} In summary, putting the Springboot program into Tomcat runs in two steps. First, Springboot initiates the class to inherit Springbootservletinitializer, overriding the Configure method. Second, change package management software packaging to war and set Spring-boot-starter-tomcat to provided. But why should you do that? According to the SERVLET3.0 specification, the Web container starts by using the Servletcontainerinitializer class to initialize the third-party component, such as registering a servlet or filter, and each framework uses servletcontainerinitialize R must be in the corresponding meta-inf/ A file named Javax.servlet.ServletContainerInitializer is created under the Services directory, and the file content specifies the specific Servletcontainerinitializer implementation class, which is springs in the SPRINGMVC framework. Ervletcontainerinitializer. Generally accompanied by the use of Servletcontainerinitializer together with the handlestypes annotation, By handlestypes you can inject some of the classes of interest into the Servletcontainerinitializerde Onstartup method as parameters. The following is the Springservletcontainerinitializer source code: @HandlesTypes (webapplicationinitializer.class) public class Springservletcontainerinitializer implements Servletcontainerinitializer {@Overridepublic void Onstartup (@Nullable Set > webappinitializerclasses, ServletContext servletcontext) throws Servletexception {List initializers = new linkedlist<> (); if (webappinitializerclasses! = null) {for (Class waiclass:webappinitializerclasses) {if (!waiclass.isinterface () &&! Modifier.isabstract (Waiclass.getmodifiers ()) && WebApplicationInitializer.class.isAssignableFrom ( Waiclass) {try {//@handlestypes (webapplicationinitializer.class) label all classes of this type are passed to the set of the Onstartup method >; creates an instance of these Webapplicationinitializer classes. 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"); r Eturn; } servletContext.log (Initializers.size () + "Spring webapplicationinitializers detected on classpath"); Annotationawareordercomparator.sort (initializers); for (Webapplicationinitializer initializer:initializers) {//Call own Onstartup for each webapplicationinitializer () Initializer.onstartup (ServletContext); }}}springbootinitializer inherits Webapplicationinitializer and overrides the Onstartup as follows: @Overridepublic void Onstartup (ServletContext ServletContext) throws Servletexception {This.logger = Logfactory.getlog (GetClass ());// Call the native Createrootapplicationcontext () method Webapplicationcontext Rootappcontext = createrootapplicationContext (ServletContext); if (rootappcontext! = null) {Servletcontext.addlistener (New Contextloaderlistener ( Rootappcontext) {@Override public void contextinitialized (Servletcontextevent event) {}});} else {this.logger.debug ("No Contextloaderlistener registered, as" + "createrootapplicationcontext () did not" + "return An application Context ");}} Protected Webapplicationcontext Createrootapplicationcontext (ServletContext servletcontext) { Springapplicationbuilder builder = Createspringapplicationbuilder (); Builder.main (GetClass ()); 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);//Call override method, override method passed in Springboot startup class Builder = Configure (builder); Builder.listeners (New Webenvironmentpropertysourceinitializer (ServletContext)); Springapplication application = Builder.build (); if (Application.getallsources (). IsEmpty () && annotationutils . Findannotation (GetClass (), configuration.class)! = null) {application.addprimarysources (Collections.singleton ( GetClass ()));} Assert.state (!application.getallsources (). IsEmpty (), "No springapplication sources has been defined. Either override the "+" Configure method or add an @Configuration annotation "); if (this.registererrorpagefilter) {applic Ation.addprimarysources (Collections.singleton (Errorpagefilterconfiguration.class));} Starting the application is to start the incoming Springboot program return run (application);} What you need to do after the program and Tomcat get through is to make the war a Docker image, and if you copy the war package every time, then the Docker build will be a hassle, and the open source community has a solution –docker-maven-plugin To see how to use GitHub, add the following to Pom.xml: com.spotify docker-maven-plugin 1.1.1 wanlinus/file-server ${project.basedir} / ${project.build.directory} ${project.build.finalname}.war There is a label in this configuration that specifies the location of the Dockerfile to build the Docker image, creating a new dockerfile at the root of the project, as follows: from Tomcatmaintainer Wanlinus workdir/dockercopy Target/file-server-0.0.1-snapshot.war./server.warrun mkdir $CATALINA _home/ Webapps/server && Mv/docker/server.war $CATALINA _home/webapps/server && unzip $CATALINA _home/webapps /server/server.war-d $CATALINA _home/webapps/server/&& rm $CATALINA _home/webapps/server/server.war & & CD $CATALINA _home/webapps/server && echo "ASD" > A.txtexpose 8080 Terminal enter MVN Clean package docker:build locally A docker image is generated, and if Docker is not running locally, you need to enter the remote address and Docker Daemon port in the label. Finally, running Docker run--rm-p 8080:8080 Wanlinus/fileserver in the terminal will see the start log of the Spring boot program after Tomcat starts, so the spring boot Tomcat is containerized.
Spring Boot Tomcat containerized deployment Practice and summary