新聞中心
環(huán)境:Spring5.3.26

創(chuàng)新互聯(lián)建站長期為上1000+客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為十堰企業(yè)提供專業(yè)的網(wǎng)站設(shè)計、成都網(wǎng)站制作,十堰網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
SpringMVC使用相信大家都會使用,別人項目工程搭建后,你只需負(fù)責(zé)寫Controller即可,那你是否想過自己能否把環(huán)境搭建出來呢?而且還不借助網(wǎng)絡(luò);本篇教大家如何通過注解快速搭建SpringMVC運(yùn)行環(huán)境。
傳統(tǒng)SpringMVC配置
本節(jié):回顧傳統(tǒng)SpringMVC的基本配置原理。
DispatcherServlet需要一個WebApplicationContext(一個普通ApplicationContext的擴(kuò)展)用于它自己的配置。WebApplicationContext有一個鏈接到ServletContext和它所關(guān)聯(lián)的Servlet。它還綁定到ServletContext,這樣應(yīng)用程序就可以在需要訪問WebApplicationContext時使用RequestContextUtils上的靜態(tài)方法來查找它。
對于許多應(yīng)用程序來說,只有一個WebApplicationContext就足夠簡單了。也可以有一個上下文層次結(jié)構(gòu),其中一個根WebApplicationContext在多個DispatcherServlet(或其他Servlet)實例之間共享,每個實例都有自己的子WebApplicationContext配置。有關(guān)上下文層次結(jié)構(gòu)特性的更多信息,請參閱ApplicationContext的附加功能。
根WebApplicationContext通常包含基礎(chǔ)設(shè)施bean,例如需要跨多個Servlet實例共享的數(shù)據(jù)存儲庫和業(yè)務(wù)服務(wù)。這些bean被有效地繼承,并且可以在特定于Servlet的子WebApplicationContext中被重寫(即重新聲明),該子WebApplicationContext通常包含給定Servlet的本地bean。下圖顯示了這種關(guān)系:
web.xml中配置:
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
/WEB-INF/root-context.xml
app1
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
/WEB-INF/app1-context.xml
1
app1
/app1/*
ContextLoaderListener:該監(jiān)聽器用來創(chuàng)建Root 容器,該容器就是用來配置基礎(chǔ)的Bean,如DAO,Service等。
DispatcherServlet:對應(yīng)一個web 容器,也就是子容器。該容器用來配置Controller。在Controller中會應(yīng)用到Service,那么該子容器就會從父容器中查找相應(yīng)的Bean。如下父子關(guān)系配置:
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
protected WebApplicationContext initWebApplicationContext() {
// 獲取父容器,該父容器是在ContextLoaderListener監(jiān)聽器中創(chuàng)建并保存到ServletContext中
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
if (this.webApplicationContext != null) {
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
if (!cwac.isActive()) {
if (cwac.getParent() == null) {
cwac.setParent(rootContext);
}
configureAndRefreshWebApplicationContext(cwac);
}
}
}
if (wac == null) {
// 創(chuàng)建子容器并設(shè)置父容器
wac = createWebApplicationContext(rootContext);
}
return wac;
}
}以上就是SpringMVC的基本配置。
Servlet注冊
既然是基于注解的方式配置SpringMVC,那么我們需要先了解Servlet的注冊方式有哪些。
方式1:
web.xml中注冊
DemoServlet
com.pack.servlet.DemoServlet
DemoServlet
/demo
方式2:
基于注解方式
@WebServlet(name = "demoServlet", urlPatterns = "/demo")
@WebServlet(value = {"/demo","/demo1"})
@WebServlet(value = "/demo")
@WebServlet("/demo")
public class DemoServlet extends HttpServlet {
// ...
}方式3:
通過SPI技術(shù),這也是今天要使用的方式
Servlet3.0以上的版本開始,可以通過SPI方式注冊Servlet,F(xiàn)ilter,Listener三大組件。
第一步:在項目中建立如下文件
META-INF/service/javax.servlet.ServletContainerInitializer文件名:javax.servlet.ServletContainerInitializer
第二步:自定義類實現(xiàn)ServletContainerInitializer
@HandlesTypes({CustomHandler.class})
public class CustomContainerInitializer implements ServletContainerInitializer {
// 這里的set集合就是當(dāng)前環(huán)境中所有CustomHandler的子類
@Override
public void onStartup(Set> set, ServletContext servletContext) throws ServletException {
if (set!=null&&set.size()>0){
set.stream().forEach(cls->{
try {
CustomHandler o = (CustomHandler)cls.newInstance();
o.onStartup();
} catch (Exception e) {
e.printStackTrace();
}
});
}
//注入Servlet
ServletRegistration.Dynamic userServlet = servletContext.addServlet("DemoServlet", DemoServlet.class);
userServlet.addMapping("/demo");
}
} SpringMVC注解配置
接下來就是要使用上面介紹的Servlet注冊方式的第三種方式來實現(xiàn)SpringMVC的注冊。
在Spring中已經(jīng)提供了相應(yīng)的實現(xiàn):
在spring-web包中:
內(nèi)容:
org.springframework.web.SpringServletContainerInitializer@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
}這里我們只需要實現(xiàn)WebApplicationInitializer接口即可,不過Spring已經(jīng)為我們定義好了該接口的抽象模版,我們只需繼承該抽象類即可:
public class SpringMVCConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class>[] getRootConfigClasses() {
return new Class>[] {RootConfig.class} ;
}
@Override
protected Class>[] getServletConfigClasses() {
return new Class>[] {WebConfig.class} ;
}
@Override
protected String[] getServletMappings() {
return new String[] {"/"} ;
}
}RootConfig.java
@Configuration
public class RootConfig {
}WebConfig.java
@Configuration
@ComponentScan(basePackages = {"com.pack.controller"})
public class WebConfig {
}測試controller
@RestController
@RequestMapping("/demo")
public class DemoController {
@GetMapping("")
public Object index() {
Map result = new HashMap<>() ;
result.put("code", 0) ;
result.put("data", "你好") ;
return result ;
}
} 測試:
只是通過如上配置,SpringMVC環(huán)境基本上是可以使用了,但是我們看上面Controller接口,是基于REST full,所以當(dāng)你訪問該接口時會出現(xiàn)如下錯誤:
這是因為默認(rèn)情況下RequestMappingHandlerAdapter無法處理,服務(wù)器端無法提供與 Accept-Charset 以及 Accept-Language 消息頭指定的值相匹配的響應(yīng)。
這時候就需要為其配置相應(yīng)的消息轉(zhuǎn)換器:
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter() ;
adapter.getMessageConverters().add(new MappingJackson2HttpMessageConverter()) ;
return adapter ;
}再次方法正常:
完畢!??!
本文題目:SpringMVC通過注解完成運(yùn)行配置,原理你都會嗎?
文章路徑:http://www.fisionsoft.com.cn/article/djcdjcc.html


咨詢
建站咨詢
