ServletContainerInitializer-- Servlet3.1 无XML启动SpringMVC

实现自己的ServletContainerInitializer

在Web容器启动的时候为提供给第三方组件做一些初始化的工作。
例如注册servlet或者filters等
servlet规范中通过ServletContainerInitializer实现次功能,每个框架再使用ServeletContainerInitlizer就必须在jar 包的META-INF/services 目录穿件一个名为javax.servlet.ServletContainerInitializer的文件 文件内容制定具体的ServletContainerInitlizer实现类

META-INF/services/javax.servlet.ServletContainerInitializer

我们的servlet类:

public class HelloService extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.write("Hello World");
        writer.flush();
    }
}

创建我们的这样的一个Initializer,并把servlet程序添加到Servlet 上下文对象当中:

@HandlesTypes(value = MyHandleType.class)
public class MyServletContainerInitializer implements ServletContainerInitializer
{

    /**
     * 作用
     * @param set
     * @param servletContext
     * @throws ServletException
     */
    @Override
    public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
        set.stream().forEach(c -> System.out.println(c.getName()));
        ServletRegistration registration = servletContext.addServlet("helloService", HelloService.class);
        registration.addMapping("/hello");
    }
}

注解HandlesTypes 的value属性标示的类的子类,或者实现累标示类接口的类,是onStartup方法中形参Set集合中的元素。

这个onStartup方法 可以获取到Servlet上下文对象,我们可以为此上下文注册Servlet对象,或者Listener对象,或者是拦截器对象。

上面的代码注册了一个Servlet ,并切设置路由为 /hello


resources/META-INF/services/javax.servlet.ServletContainerInitializer文件中加入你的实现了ServletContainerInitializer接口的类。

crown.config.MyServletContainerInitializer

把应用部署到Tomcat 启动 在浏览器输入localhost:8080/hello

使用WebApplicationInitializer 实现无Web.xml的SpringMVC 程序

新建项目MyMvc3,导入servlet jar ,跟Spring-webmvc的jar包

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.8.RELEASE</version>
</dependency>

打开

路径:
spring-web-5.1.8.RELEASE.jar!/META-INF/services/javax.servlet.ServletContainerInitializer

内容:
org.springframework.web.SpringServletContainerInitializer

接着上面的话 :我们在META-INF/services/javax.servlet.ServletContainerInitializer 中定义的class :SpringServletContainerInitializer

@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    public SpringServletContainerInitializer() {
    }

    public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
        List<WebApplicationInitializer> initializers = new LinkedList();
        Iterator var4;
        //有类实现了WebApplicationInitializer 就把实现了的都加到Set集合当中
        if (webAppInitializerClasses != null) {
            var4 = webAppInitializerClasses.iterator();

            while(var4.hasNext()) {
                Class<?> waiClass = (Class)var4.next();
                if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                    try {
                        initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass, new Class[0]).newInstance());
                    } catch (Throwable var7) {
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
                    }
                }
            }
        }

        //集合为空就是表示没有类继承WebApplicationInitializer
        if (initializers.isEmpty()) {
            servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
        } else {
            
            servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
            AnnotationAwareOrderComparator.sort(initializers);
            var4 = initializers.iterator();
            //调用每个实现累Webinitializer的onStartup方法,并传入当前的上下文对象
            while(var4.hasNext()) {
                WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
                initializer.onStartup(servletContext);
            }

        }
    }
}

首先它的HandlesTypes是WebApplicationInitializer

public interface WebApplicationInitializer {
    void onStartup(ServletContext var1) throws ServletException;
}

它是一个接口 如果我们实现了它 就可以去添加Servlet到容器的上下文对象。

首先创建用来测试的Controller

com.crown.controller.HelloController

@RestController("/")
public class HelloController {

    @GetMapping("/hello")
    public String hello(){
        return "Hello World";
    }
}

创建配置类

@Configuration
//开启注解
@EnableWebMvc
@ComponentScan(basePackages = "com.crown.controller")
public class MyMvcConfig {

}

下面创建我们最为主要的

public class MyWebInitializer  implements WebApplicationInitializer {

    @Override
    public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {
        //创建Web上下文
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        //注册我们的配置类 让他去加载我们需要扫包的类
        context.register(MyMvcConfig.class);
        //把DispatcherServlet程序放到servlet 上下文当中
        ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet",new DispatcherServlet(context));
        //拦截所有的请求
        registration.addMapping("/");
        //最高优先级启动
        registration.setLoadOnStartup(1);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值