Springboot—Web原生组件注入

 问:怎么将原生组件注入到容器中?

目录

方法一:使用Servlet原生API:

方式二:使用RegistrationBean

扩展:DispatcherServlet如何注册进来:


方法一:使用Servlet原生API:

首先我们先定义好我们自定义的web三大组件:Servlet、Filter、Listener:

Servlet:注意标上@WebServlet(urlPatterns="xxx")指定资源路径,用来访问它

这里注意:根据精确优选原则,MyServlet处理的请求比DispatcherServlet更加精确,所以这里是由原生的Servlet(Tomcat)处理,而拦截器处理的是啥?是DispatcherServlet(Spring)处理的请求才会被拦截器处理;

@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("6666");
    }
}

Filter:

三个关键:1.@WebFilter(urlPatterns={xxx});2.实现Filter;3.doFilter(req,resp);

  @Slf4j
    @WebFilter(urlPatterns = {"/css/*","/images/*"})
public class PraFilter implements Filter {


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("PraFilter正在工作");
//        下一个filter
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

Listener:


@Slf4j
@WebListener
public class MySwervletContextListener implements ServletContextListener {


    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("MySwervletContextListener监听到项目初始化完成");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("MySwervletContextListener监听到项目销毁");
    }
}

然后我们需要在主启动类标上@ServletComponentScan(basePages="xxx.xxx"):自动指定了Servlet原生组件放在哪里;

@ServletComponentScan(basePackages = "com.atguigu.admin")
@SpringBootApplication(exclude = RedisAutoConfiguration.class)
public class Boot05WebAdminApplication {

    public static void main(String[] args) {
        SpringApplication.run(Boot05WebAdminApplication.class, args);

    }

方式二:使用RegistrationBean

分别用ServletRegisterationBean、Filterxxx、Listenerxxx将组件注入到容器中

package com.atguigu.admin.Practice;

import com.atguigu.admin.servlet.MyFilter;
import com.atguigu.admin.servlet.MyServlet;
import com.atguigu.admin.servlet.MySwervletContextListener;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;

/**
 * @author diao 2022/2/6
 */

//我们将自定义的Filter、Listener...放在容器中,在配置类中注册到容器
    @Configuration(proxyBeanMethods = true)
    //这里不能是false,因为下面的Filter可能还会调用上面的servlet,会重新创建,数据冗余
public class ServletRegisterConfig { 
        @Bean
        public ServletRegistrationBean myServlet(){
             MyServlet myServlet = new MyServlet();
            return new ServletRegistrationBean(myServlet,"/my");
        }
        @Bean
        public FilterRegistrationBean myFilter(){
            //得到自定义的filter
            MyFilter myFilter = new MyFilter();
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
            //设置过滤的路径,setUrlPatterns()里面参数为集合
            filterRegistrationBean.setUrlPatterns(Arrays.asList("/my"));
            return filterRegistrationBean;
        }
        @Bean
        public ServletListenerRegistrationBean myListener(){
            //得到自定义的Listener
            MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();
            return new ServletListenerRegistrationBean(mySwervletContextListener);
        }
}

扩展:DispatcherServlet如何注册进来:

  容器中自动配置了DispatcherServlet属性绑定了WebMvcProperties中:配置文件选项为:spring.mvc...,我们可以修改Dispatcher转发的路径:

Springboot—Web原生组件注入_第1张图片

 WebMvcProperties中对Servlet的路径部分代码:

public static class Servlet {
        private String path = "/";
        private int loadOnStartup = -1;

        public Servlet() {
        }

        public String getPath() {
            return this.path;
        }

        public void setPath(String path) {
            Assert.notNull(path, "Path must not be null");
            Assert.isTrue(!path.contains("*"), "Path must not contain wildcards");
            this.path = path;
        }

        public int getLoadOnStartup() {
            return this.loadOnStartup;
        }

        public void setLoadOnStartup(int loadOnStartup) {
            this.loadOnStartup = loadOnStartup;
        }

        public String getServletMapping() {
            if (!this.path.equals("") && !this.path.equals("/")) {
                return this.path.endsWith("/") ? this.path + "*" : this.path + "/*";
            } else {
                return "/";
            }
        }

        public String getPath(String path) {
            String prefix = this.getServletPrefix();
            if (!path.startsWith("/")) {
                path = "/" + path;
            }

            return prefix + path;
        }

        public String getServletPrefix() {
            String result = this.path;
            int index = result.indexOf(42);
            if (index != -1) {
                result = result.substring(0, index);
            }

            if (result.endsWith("/")) {
                result = result.substring(0, result.length() - 1);
            }

            return result;
        }

你可能感兴趣的:(springboot,JavaWeb,spring,boot,前端,spring)