03)java spi应用 java spring web项目 去除web.xml
?
上一節 學習完了 原始 java web項目 無web.xml怎么配置servlet
這節學習 java web項目 無web.xml怎么集成spring框架
?
使用過web.xml集成spring框架的同學應該對下面2個web.xml的配置都熟悉
?
spring的ContextLoaderListener監聽器實現了ServletContextListener監聽器
在web應用啟動時會自動執行contextInitialized方法,尋找spring的配置文件application.xml,完成spring容器的啟動工作
web.xml配置springmvc DispatcherServlet 如下,去除web.xml后? 都需要有對應的解決方案
好了,下面開始學習去除web.xml的集成spring的方法
?
1. 新建一個maven web項目?
上一節普通java web項目保留 ,新建一個maven web項目,建好后先刪除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設置為provided不會打包到項目lib,項目在tomcat運行時 tomcat lib下已經有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項目META-INF/service我們配置的javax.servlet.ServletContainerInitializer是指向的自己寫的實現類
?使用spring框架,spring已經提供了實現類,并且spring-web? META-INF/service 配置好了javax.servlet.ServletContainerInitializer,指向了spring的實現類,這樣tomcat啟動時就會執行spring實現類的onStartup方法
?
spring實現類位于? spring-web-4.3.12.RELEASE.jar ?org.springframework.web.SpringServletContainerInitializer
查看spring源碼,該類org.springframework.web.SpringServletContainerInitializer實現了servlet-api的ServletContainerInitializer接口
?
并且class上有一個@HandlesTypes({WebApplicationInitializer.class})注解,是servlet提供的javax.servlet.annotation.HandlesTypes,它配置的value為WebApplicationInitializer.class}
查看源碼可以發現onStart會尋找HandlesTypes配置的class的子類,并執行WebApplicationInitializer子類的onStartup方法
這其實也很好理解?META-INF/service?javax.servlet.ServletContainerInitializer是指向的spring的實現類,這個是編譯成class的,我們無法修改,但是我們肯定是要寫自己的邏輯的,所以通過HandlesTypes擴展
比如加載spring配置文件,啟動spring容器,配置spring mvc?DispatcherServlet, 配置普通的servlet 監聽器等,
?
?
?
4.查看spring-web自帶配置META-INF/service??javax.servlet.ServletContainerInitializer文件
有個警告,idea還是比較智能的,因為SpringServletContainerInitializer實現了ServletContainerInitializer.class,不引入servlet-api.jar找不到ServletContainerInitializer.class
?
pom.xml引入servlet-api.jar ,警告消失
<!-- 引入 servlet-api.jar scope設置為provided不會打包到項目lib,項目在tomcat運行時 tomcat lib下已經有servlet-api.jar--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency>?
?
5.先啟動tomcat測試一波
?
因為我們還沒編寫實現WebApplicationInitializer的類,?initializers.isEmpty()執行為true,將輸入以下日志
但是我idea debug class進入了,server沒打印出這個log,因為servletContext.log是打印在Tomcat Localhost Log中
6.一步一步來,接下來編寫 class 實現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:編寫實現類 實現WebApplicationInitializer* 這樣tomcat啟動時 先執行SpringServletContainerInitializer.class的onStartup方法* 在通過HandlesTypes配置 執行該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 啟動spring容器============");// 代替 web.xml 中的 listener 初始化//<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>AnnotationConfigWebApplicationContext ac_spring = new AnnotationConfigWebApplicationContext();// listener中的加載spring.xml的配置文件內容 MySpringXml.class代替 spring.xmlac_spring.register(MySpringXml.class);//用于初始化spring配置文件 web項目可用可不用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項目可用可不用//配置spring dispatcherServlet 代替web.xml// <servlet-name>springDispatcher</servlet-name>//<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>DispatcherServlet dispatcherServlet = new DispatcherServlet(ac_mvc);//創建前端控制器去名字為dispatcherServlet <servlet>標簽ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", dispatcherServlet);//啟動順序設置為1 tomcat啟動時就初始化該servletregistration.setLoadOnStartup(1);//<servlet-mapping>里面的url-pattenregistration.addMapping("*.do");System.out.println("=========MySpringInitializer onStartup 運行完畢============");} }MySpringXml.class
package com.wying.web;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;/*** 相當于spring.xml文件* description:spring提供了使用代碼去除 spring.xml配置文件的方式* 、。。既然servlet3.0 開始都去除web.xml了 spring也提供了一套去除自家xml配置的方法* 該class通過代碼配置xml的內容* date: 2021/3/19* author: gaom* version: 1.0*/@Configuration @ComponentScan(basePackages = "com.wying") public class MySpringXml {//目前測試效果 不連接數據庫// 配置datasource sessionFactory 也一樣 通過@Bean注解 規則都差不多 xml的配置 都有對應的class method對應 }?
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;/**相當于spring-mvc.xml文件* description:spring提供了使用代碼去除 spring-mvc.xml配置文件的方式* 、。。既然servlet3.0 開始都去除web.xml了 spring也提供了一套去除自家xml配置的方法* 該class通過代碼配置spring-mvc.xml的內容* 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新建一個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啟動項目
成功打印出spring初始化日志
瀏覽器測試效果
http://localhost:8082/JavaSpringWebNoWebxmlDemo_war_exploded/訪問項目根目錄成功讀取默認的index.jsp文件
http://localhost:8082/JavaSpringWebNoWebxmlDemo_war_exploded/test.do?測試controller,成功讀取到jsp頁面
?
8.使用spring.xml文件
?
目前已經實現去除web.xml和spring的所有配置文件,但是實際項目中我并不這么用,
使用java文件配置spring xml不方便,編譯成class不好改動,雖然可以建立一個properties配置文件,java配置讀取properties配置,但是有時xml也是需要改動的,
?所以下面記錄下使用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:編寫實現類 實現WebApplicationInitializer* 這樣tomcat啟動時 先執行SpringServletContainerInitializer.class的onStartup方法* 在通過HandlesTypes配置 執行該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 啟動spring容器============");// 代替 web.xml 中的 listener 初始化//<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>AnnotationConfigWebApplicationContext ac_spring = new AnnotationConfigWebApplicationContext();// listener中的加載spring.xml的配置文件內容 MySpringXml.class代替 spring.xmlac_spring.register(MySpringXml.class);//用于初始化spring配置文件 web項目可用可不用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項目可用可不用//配置spring dispatcherServlet 代替web.xml// <servlet-name>springDispatcher</servlet-name>//<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>DispatcherServlet dispatcherServlet = new DispatcherServlet(ac_mvc);//創建前端控制器去名字為dispatcherServlet <servlet>標簽ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", dispatcherServlet);//啟動順序設置為1 tomcat啟動時就初始化該servletregistration.setLoadOnStartup(1);//<servlet-mapping>里面的url-pattenregistration.addMapping("*.do");System.out.println("=========MySpringInitializer onStartup 運行完畢============");}*///讀取spring.xml 配置文件的方式@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {System.out.println("保留spring.xml方式=========MySpringInitializer onStartup============");System.out.println("=========MySpringInitializer 啟動spring容器============");servletContext.setInitParameter("contextConfigLocation","classpath:spring.xml");//springMVC的servlet//添加監聽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 運行完畢============");} }?
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>啟動項目
啟動成功,并打印出讀取spring.xml的方式
測試效果
和java文件代替xml效果一樣,完成
?
項目源碼已上傳github,需要的同學可以下載
?https://github.com/gaomeng6319/JavaSpringWebNoWebxmlDemo
?
總結
以上是生活随笔為你收集整理的03)java spi应用 java spring web项目 去除web.xml的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Go语言写界面】一、使用xcgui完成
- 下一篇: ipvsadm基本设置