SpringBoot是Spring全家桶的成员之一,基于约定优于配置的思想(即有约定默认值,在不配置的情况下会使用默认值,在配置文件下配置的话会使用配置的值)。SpringBoot是一种整合Spring技术栈的方式(或者说是框架),同时也是简化Spring的一种快速开发
原生组件注入SpringBoot,即注册 Servlet 、Filter、Listener 进入 SpringBoot
一、使用 Servlet API
使用 Servlet API 可以实现原生组件注入,通过在自定义 Servlet 前加入 @WebServlet
注释,并且在 SpringBoot 启动类前加入 @ServletComponentScan
注释,可实现注册 Servlet
代码示例:
1、实现自定义 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、实现自定义 MyFilter
@Slf4j
@WebFilter(urlPatterns = {"/css/*", "/images/*"}) // 拦截静态资源
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、实现自定义 MyServletContextListener
@WebListener
@Slf4j
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
log.info("MyServletContextListener 监听到项目初始化完成");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log.info("MyServletContextListener 监听到项目销毁");
}
}
二、使用 RegistrationBean 的方式注入原生组件
通过编写 MyRegistConfig 配置类,返回 RegistrationBean 的方式实现组件的注入,与上一种方式的区别在于,这种方式不需要给 自定义 Servlet 类写 @WebServlet 注释。
注意点:要记得使用 @Bean 注释将 ServletRegistrationBean 注册到容器中。
代码示例:
自定义 MyRegistConfig 配置类,注册 myServlet 组件,返回 ServletRegistrationBean 对象 (对象参数为自定义的 myServlet 对象实例)
myFilter 及myListener 的实现方式同理
@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 开发,如果多个 Servlet 都能处理到同一层路径,是精确优先原则,例如:
A:/my/
B: /my/1
发送 /my/1 请求 B处理,而发送 /my/2 请求 A 处理
结论 : 来到 /my 不经过 / —— 精确匹配 /my 直接经 Tomcat 写出响应,不经过 SpringMVC 的一系列流程,因此不被拦截器拦截,如下图所示:
到此这篇关于SpringBoot原生组件注入实现两种方式介绍的文章就介绍到这了,更多相关SpringBoot原生组件注入内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
本文标题为:SpringBoot原生组件注入实现两种方式介绍
基础教程推荐
- Java实现查找文件和替换文件内容 2023-04-06
- springboot自定义starter方法及注解实例 2023-03-31
- Java实现线程插队的示例代码 2022-09-03
- ConditionalOnProperty配置swagger不生效问题及解决 2023-01-02
- java实现多人聊天系统 2023-05-19
- java基础知识之FileInputStream流的使用 2023-08-11
- Java文件管理操作的知识点整理 2023-05-19
- Java数据结构之对象比较详解 2023-03-07
- Java并发编程进阶之线程控制篇 2023-03-07
- JDK数组阻塞队列源码深入分析总结 2023-04-18