问:怎么将原生组件注入到容器中?
目录
方法一:使用Servlet原生API:
方式二:使用RegistrationBean
扩展:DispatcherServlet如何注册进来:
首先我们先定义好我们自定义的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);
}
分别用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属性绑定了WebMvcProperties中:配置文件选项为:spring.mvc...,我们可以修改Dispatcher转发的路径:
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;
}