03)java spi应用 java spring web项目 去除web.xml
?
上一節(jié) 學(xué)習(xí)完了 原始 java web項(xiàng)目 無web.xml怎么配置servlet
這節(jié)學(xué)習(xí) java web項(xiàng)目 無web.xml怎么集成spring框架
?
使用過web.xml集成spring框架的同學(xué)應(yīng)該對下面2個(gè)web.xml的配置都熟悉
?
spring的ContextLoaderListener監(jiān)聽器實(shí)現(xiàn)了ServletContextListener監(jiān)聽器
在web應(yīng)用啟動(dòng)時(shí)會(huì)自動(dòng)執(zhí)行contextInitialized方法,尋找spring的配置文件application.xml,完成spring容器的啟動(dòng)工作
web.xml配置springmvc DispatcherServlet 如下,去除web.xml后? 都需要有對應(yīng)的解決方案
好了,下面開始學(xué)習(xí)去除web.xml的集成spring的方法
?
1. 新建一個(gè)maven web項(xiàng)目?
上一節(jié)普通java web項(xiàng)目保留 ,新建一個(gè)maven web項(xiàng)目,建好后先刪除web.xml文件
?
2.pom.xml引入spring依賴
pom.xml如下 使用的是spring? 4.3.12 正式版本
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.wying</groupId><artifactId>JavaSpringWebNoWebxmlDemo</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>JavaSpringWebNoWebxmlDemo Maven Webapp</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target><spring.version>4.3.12.RELEASE</spring.version></properties><dependencies><!-- 引入 servlet-api.jar scope設(shè)置為provided不會(huì)打包到項(xiàng)目lib,項(xiàng)目在tomcat運(yùn)行時(shí) tomcat lib下已經(jīng)有servlet-api.jar--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency></dependencies><build><finalName>JavaSpringWebNoWebxmlDemo</finalName><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin></plugins></pluginManagement></build> </project>?
3.spring 去除web.xml原理
普通java web項(xiàng)目META-INF/service我們配置的javax.servlet.ServletContainerInitializer是指向的自己寫的實(shí)現(xiàn)類
?使用spring框架,spring已經(jīng)提供了實(shí)現(xiàn)類,并且spring-web? META-INF/service 配置好了javax.servlet.ServletContainerInitializer,指向了spring的實(shí)現(xiàn)類,這樣tomcat啟動(dòng)時(shí)就會(huì)執(zhí)行spring實(shí)現(xiàn)類的onStartup方法
?
spring實(shí)現(xiàn)類位于? spring-web-4.3.12.RELEASE.jar ?org.springframework.web.SpringServletContainerInitializer
查看spring源碼,該類org.springframework.web.SpringServletContainerInitializer實(shí)現(xiàn)了servlet-api的ServletContainerInitializer接口
?
并且class上有一個(gè)@HandlesTypes({WebApplicationInitializer.class})注解,是servlet提供的javax.servlet.annotation.HandlesTypes,它配置的value為WebApplicationInitializer.class}
查看源碼可以發(fā)現(xiàn)onStart會(huì)尋找HandlesTypes配置的class的子類,并執(zhí)行WebApplicationInitializer子類的onStartup方法
這其實(shí)也很好理解?META-INF/service?javax.servlet.ServletContainerInitializer是指向的spring的實(shí)現(xiàn)類,這個(gè)是編譯成class的,我們無法修改,但是我們肯定是要寫自己的邏輯的,所以通過HandlesTypes擴(kuò)展
比如加載spring配置文件,啟動(dòng)spring容器,配置spring mvc?DispatcherServlet, 配置普通的servlet 監(jiān)聽器等,
?
?
?
4.查看spring-web自帶配置META-INF/service??javax.servlet.ServletContainerInitializer文件
有個(gè)警告,idea還是比較智能的,因?yàn)镾pringServletContainerInitializer實(shí)現(xiàn)了ServletContainerInitializer.class,不引入servlet-api.jar找不到ServletContainerInitializer.class
?
pom.xml引入servlet-api.jar ,警告消失
<!-- 引入 servlet-api.jar scope設(shè)置為provided不會(huì)打包到項(xiàng)目lib,項(xiàng)目在tomcat運(yùn)行時(shí) tomcat lib下已經(jīng)有servlet-api.jar--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency>?
?
5.先啟動(dòng)tomcat測試一波
?
因?yàn)槲覀冞€沒編寫實(shí)現(xiàn)WebApplicationInitializer的類,?initializers.isEmpty()執(zhí)行為true,將輸入以下日志
但是我idea debug class進(jìn)入了,server沒打印出這個(gè)log,因?yàn)閟ervletContext.log是打印在Tomcat Localhost Log中
6.一步一步來,接下來編寫 class 實(shí)現(xiàn)WebApplicationInitializer.class
MySpringInitializer.class
package com.wying.web;import org.springframework.stereotype.Component; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet;import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration;/*** description:編寫實(shí)現(xiàn)類 實(shí)現(xiàn)WebApplicationInitializer* 這樣tomcat啟動(dòng)時(shí) 先執(zhí)行SpringServletContainerInitializer.class的onStartup方法* 在通過HandlesTypes配置 執(zhí)行該class的onStartup方法* date: 2021/3/19* author: gaom* version: 1.0*/public class MySpringInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {System.out.println("=========MySpringInitializer onStartup============");System.out.println("=========MySpringInitializer 啟動(dòng)spring容器============");// 代替 web.xml 中的 listener 初始化//<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>AnnotationConfigWebApplicationContext ac_spring = new AnnotationConfigWebApplicationContext();// listener中的加載spring.xml的配置文件內(nèi)容 MySpringXml.class代替 spring.xmlac_spring.register(MySpringXml.class);//用于初始化spring配置文件 web項(xiàng)目可用可不用servletContext.addListener(new ContextLoaderListener(ac_spring));System.out.println("=========MySpringInitializer 配置srping dispatcherServlet============");AnnotationConfigWebApplicationContext ac_mvc = new AnnotationConfigWebApplicationContext();//MySpringMvcXml.class代替 spring-mvc.xmlac_mvc.register(MySpringMvcXml.class);//用于初始化spring配置文件 web項(xiàng)目可用可不用//配置spring dispatcherServlet 代替web.xml// <servlet-name>springDispatcher</servlet-name>//<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>DispatcherServlet dispatcherServlet = new DispatcherServlet(ac_mvc);//創(chuàng)建前端控制器去名字為dispatcherServlet <servlet>標(biāo)簽ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", dispatcherServlet);//啟動(dòng)順序設(shè)置為1 tomcat啟動(dòng)時(shí)就初始化該servletregistration.setLoadOnStartup(1);//<servlet-mapping>里面的url-pattenregistration.addMapping("*.do");System.out.println("=========MySpringInitializer onStartup 運(yùn)行完畢============");} }MySpringXml.class
package com.wying.web;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;/*** 相當(dāng)于spring.xml文件* description:spring提供了使用代碼去除 spring.xml配置文件的方式* 、。。既然servlet3.0 開始都去除web.xml了 spring也提供了一套去除自家xml配置的方法* 該class通過代碼配置xml的內(nèi)容* date: 2021/3/19* author: gaom* version: 1.0*/@Configuration @ComponentScan(basePackages = "com.wying") public class MySpringXml {//目前測試效果 不連接數(shù)據(jù)庫// 配置datasource sessionFactory 也一樣 通過@Bean注解 規(guī)則都差不多 xml的配置 都有對應(yīng)的class method對應(yīng) }?
MySpringMvcXml.class
package com.wying.web;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver;/**相當(dāng)于spring-mvc.xml文件* description:spring提供了使用代碼去除 spring-mvc.xml配置文件的方式* 、。。既然servlet3.0 開始都去除web.xml了 spring也提供了一套去除自家xml配置的方法* 該class通過代碼配置spring-mvc.xml的內(nèi)容* date: 2021/3/19* author: gaom* version: 1.0*/@Configuration @EnableWebMvc //開啟支持mvc @ComponentScan(basePackages = "com.wying") public class MySpringMvcXml {/*** 代替spring-mvc.xml* <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolve">* @return*/@Beanpublic InternalResourceViewResolver internalResourceViewResolver() {InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();viewResolver.setPrefix("/WEB-INF/views/");viewResolver.setSuffix(".jsp");return viewResolver;}} TestController.class新建一個(gè)controller,用于測試spring-mvc DispatcherServlet是否配置成功
package com.wying.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;/*** description:測試controller* date: 2021/3/19* author: gaom* version: 1.0*/ @Controller public class TestController {@RequestMapping(value="test.do")public String testjsp(){return "test";} }7.tomcat啟動(dòng)項(xiàng)目
成功打印出spring初始化日志
瀏覽器測試效果
http://localhost:8082/JavaSpringWebNoWebxmlDemo_war_exploded/訪問項(xiàng)目根目錄成功讀取默認(rèn)的index.jsp文件
http://localhost:8082/JavaSpringWebNoWebxmlDemo_war_exploded/test.do?測試controller,成功讀取到j(luò)sp頁面
?
8.使用spring.xml文件
?
目前已經(jīng)實(shí)現(xiàn)去除web.xml和spring的所有配置文件,但是實(shí)際項(xiàng)目中我并不這么用,
使用java文件配置spring xml不方便,編譯成class不好改動(dòng),雖然可以建立一個(gè)properties配置文件,java配置讀取properties配置,但是有時(shí)xml也是需要改動(dòng)的,
?所以下面記錄下使用spring.xml文件的方法
?
修改MySpringInitializer.class?onStartup方法 改成讀取spring.xml配置文件的方式
package com.wying.web;import org.springframework.stereotype.Component; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet;import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration;/*** description:編寫實(shí)現(xiàn)類 實(shí)現(xiàn)WebApplicationInitializer* 這樣tomcat啟動(dòng)時(shí) 先執(zhí)行SpringServletContainerInitializer.class的onStartup方法* 在通過HandlesTypes配置 執(zhí)行該class的onStartup方法* date: 2021/3/19* author: gaom* version: 1.0*/public class MySpringInitializer implements WebApplicationInitializer {//spring配置文件也去除的方式/* @Overridepublic void onStartup(ServletContext servletContext) throws ServletException {System.out.println("=========MySpringInitializer onStartup============");System.out.println("=========MySpringInitializer 啟動(dòng)spring容器============");// 代替 web.xml 中的 listener 初始化//<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>AnnotationConfigWebApplicationContext ac_spring = new AnnotationConfigWebApplicationContext();// listener中的加載spring.xml的配置文件內(nèi)容 MySpringXml.class代替 spring.xmlac_spring.register(MySpringXml.class);//用于初始化spring配置文件 web項(xiàng)目可用可不用servletContext.addListener(new ContextLoaderListener(ac_spring));System.out.println("=========MySpringInitializer 配置srping dispatcherServlet============");AnnotationConfigWebApplicationContext ac_mvc = new AnnotationConfigWebApplicationContext();//MySpringMvcXml.class代替 spring-mvc.xmlac_mvc.register(MySpringMvcXml.class);//用于初始化spring配置文件 web項(xiàng)目可用可不用//配置spring dispatcherServlet 代替web.xml// <servlet-name>springDispatcher</servlet-name>//<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>DispatcherServlet dispatcherServlet = new DispatcherServlet(ac_mvc);//創(chuàng)建前端控制器去名字為dispatcherServlet <servlet>標(biāo)簽ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", dispatcherServlet);//啟動(dòng)順序設(shè)置為1 tomcat啟動(dòng)時(shí)就初始化該servletregistration.setLoadOnStartup(1);//<servlet-mapping>里面的url-pattenregistration.addMapping("*.do");System.out.println("=========MySpringInitializer onStartup 運(yùn)行完畢============");}*///讀取spring.xml 配置文件的方式@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {System.out.println("保留spring.xml方式=========MySpringInitializer onStartup============");System.out.println("=========MySpringInitializer 啟動(dòng)spring容器============");servletContext.setInitParameter("contextConfigLocation","classpath:spring.xml");//springMVC的servlet//添加監(jiān)聽servletContext.addListener(new ContextLoaderListener());System.out.println("=========MySpringInitializer 配置srping dispatcherServlet============");ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet());dispatcher.setLoadOnStartup(1);dispatcher.addMapping("*.do");dispatcher.setInitParameter("contextConfigLocation","classpath:spring-mvc.xml");System.out.println("=========MySpringInitializer onStartup 運(yùn)行完畢============");} }?
spring.xml 文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><context:component-scan base-package="com.wying"/></beans>spring-mvc.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><context:component-scan base-package="com.wying"/><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"></property><property name="suffix" value=".jsp"></property></bean></beans>啟動(dòng)項(xiàng)目
啟動(dòng)成功,并打印出讀取spring.xml的方式
測試效果
和java文件代替xml效果一樣,完成
?
項(xiàng)目源碼已上傳github,需要的同學(xué)可以下載
?https://github.com/gaomeng6319/JavaSpringWebNoWebxmlDemo
?
總結(jié)
以上是生活随笔為你收集整理的03)java spi应用 java spring web项目 去除web.xml的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Go语言写界面】一、使用xcgui完成
- 下一篇: ipvsadm基本设置