SpringBoot原生組件注入實現(xiàn)兩種方式介紹
原生組件注入SpringBoot,即注冊 Servlet 、Filter、Listener 進入 SpringBoot
一、使用 Servlet API
使用 Servlet API 可以實現(xiàn)原生組件注入,通過在自定義 Servlet 前加入 @WebServlet 注釋,并且在 SpringBoot 啟動類前加入 @ServletComponentScan 注釋,可實現(xiàn)注冊 Servlet
代碼示例:
1、實現(xiàn)自定義 MyServlet
自定義 Servlet 類:
@WebServlet(urlPatterns = "/my") // 加入 @WebServlet 注釋
public class MyServlet extends HttpServlet { // 注意要繼承 HttpServlet 類
@Override // 重寫 DoGet 方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("haha");
}
}
項目啟動類:
@ServletComponentScan(basePackages = "com.wanqing.admin") //掃描那個包中有servlet
@SpringBootApplication
public class DemoAdminApplication {
public static void main(String[] args) {
SpringApplication.run(DemoAdminApplication.class, args);
}
}
2、實現(xiàn)自定義 MyFilter
@Slf4j
@WebFilter(urlPatterns = {"/css/*", "/images/*"}) // 攔截靜態(tài)資源
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
log.info("MyFilter初始化完成");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("MyFilter工作");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
log.info("MyFilter銷毀");
}
}3、實現(xiàn)自定義 MyServletContextListener
@WebListener
@Slf4j
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
log.info("MyServletContextListener 監(jiān)聽到項目初始化完成");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log.info("MyServletContextListener 監(jiān)聽到項目銷毀");
}
}二、使用 RegistrationBean 的方式注入原生組件
通過編寫 MyRegistConfig 配置類,返回 RegistrationBean 的方式實現(xiàn)組件的注入,與上一種方式的區(qū)別在于,這種方式不需要給 自定義 Servlet 類寫 @WebServlet 注釋。
注意點:要記得使用 @Bean 注釋將 ServletRegistrationBean 注冊到容器中。
代碼示例:
自定義 MyRegistConfig 配置類,注冊 myServlet 組件,返回 ServletRegistrationBean 對象 (對象參數(shù)為自定義的 myServlet 對象實例)
myFilter 及myListener 的實現(xiàn)方式同理
@Configuration
public class MyRegistConfig {
@Bean
public ServletRegistrationBean myServlet(){
MyServlet myServlet = new MyServlet();
return new ServletRegistrationBean(myServlet, "/my","/my02");
}
@Bean
public FilterRegistrationBean myFilter(){
MyFilter filter = new MyFilter();
//return new FilterRegistrationBean(filter, myServlet()); // 攔截myServlet()的路徑
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(filter);
filterRegistrationBean.addUrlPatterns("/my","/css/*");
return filterRegistrationBean;
}
@Bean
public ServletListenerRegistrationBean myListener(){
MyServletContextListener myServletContextListener = new MyServletContextListener();
return new ServletListenerRegistrationBean(myServletContextListener);
}
}拓展:為什么攔截器不攔截 我們自定義的 MyServlet 請求?
分析 DispatcherServlet 如何注冊進入容器中,從 DispatcherServletAutoConfiguration 類開始
容器中自動配置了 DispatcherServlet 組件,其屬性綁定到 WebMvcProperties 中,對應的配置文件是 spring.mvc
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) // 注冊 DispatcherServlet 組件
public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());
dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());
dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails());
return dispatcherServlet;
}
通過 ServletRegistrationBean < DispatcherServlet > 機制(DispatcherServletRegistrationBean.class)將 DispatcherServlet 原生的 Servlet 組件配置進來
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet,
WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet,
webMvcProperties.getServlet().getPath()); // 拿到默認映射路徑為 / 路徑
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}拿到默認映射路徑 /
WebMvcProperties.class 中配置

使用 Tomcat 做原生 Servlet 開發(fā),如果多個 Servlet 都能處理到同一層路徑,是精確優(yōu)先原則,例如:
A:/my/
B: /my/1
發(fā)送 /my/1 請求 B處理,而發(fā)送 /my/2 請求 A 處理
結(jié)論 : 來到 /my 不經(jīng)過 / —— 精確匹配 /my 直接經(jīng) Tomcat 寫出響應,不經(jīng)過 SpringMVC 的一系列流程,因此不被攔截器攔截,如下圖所示:

到此這篇關(guān)于SpringBoot原生組件注入實現(xiàn)兩種方式介紹的文章就介紹到這了,更多相關(guān)SpringBoot原生組件注入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Spring Cache和Redis實現(xiàn)查詢數(shù)據(jù)緩存
在現(xiàn)代應用程序中,查詢緩存的使用已經(jīng)變得越來越普遍,它不僅能夠顯著提高系統(tǒng)的性能,還能提升用戶體驗,在這篇文章中,我們將探討緩存的基本概念、重要性以及如何使用Spring Cache和Redis實現(xiàn)查詢數(shù)據(jù)緩存,需要的朋友可以參考下2024-07-07
詳解Java編寫算法時如何加快讀寫數(shù)據(jù)速度
這篇文章主要為大家詳細介紹了Java在編寫算法時如何加快讀寫數(shù)據(jù)速度,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-03-03

