• Servlet3.0的动态


    动态的创建是为了简化配置文件的.对于我们创建的servlet,filter和listener后可以使用。这也是注解的另外一种替代方式。

    动态的添加有两种,一种是基于ContextListener的,另外一种是基于servlet3.0新增接口的ServletContainerInitializer的

    动态的主要类是Dynamic

    代码:

    package com.hotusm.dynamic;
    
    import javax.servlet.FilterRegistration;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.ServletRegistration;
    import javax.servlet.annotation.WebListener;
    
    @WebListener
    public class DynamicInitContextListener implements ServletContextListener{
    
        public void contextInitialized(ServletContextEvent sce) {
            
            ServletContext context = sce.getServletContext();
            ServletRegistration.Dynamic dynamicServlet=context.addServlet("dynamicServlet", DynamicServlet.class); 
            dynamicServlet.addMapping("/dynamicServlet");
            dynamicServlet.setAsyncSupported(true);
            dynamicServlet.setLoadOnStartup(1);
            
            FilterRegistration.Dynamic dynamicFilter = context.addFilter("dynamicFilter", DynamicFilter.class);
            
            context.addListener("com.hotusm.dynamic.DynamicListener");
            
        }
    
        public void contextDestroyed(ServletContextEvent sce) {
            
        }
    
    }

    ServletContainerInitializer的:

    package com.hotusm.dynamic;
    
    import java.util.Set;
    
    import javax.servlet.ServletContainerInitializer;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.HandlesTypes;
    import javax.servlet.http.HttpServlet;
    public class ServletContainerInitializerImpl implements ServletContainerInitializer{
    
        public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
            
            System.out.println("ServletContainerInitializer");
            
            if(c!=null){
                for(Class<?> clazz:c){
                    System.out.println(clazz.getClass().getName());
                }
            }
            
    //        ServletContext context = sce.getServletContext();
    //        ServletRegistration.Dynamic dynamicServlet=context.addServlet("dynamicServlet", DynamicServlet.class); 
    //        dynamicServlet.addMapping("/dynamicServlet");
    //        dynamicServlet.setAsyncSupported(true);
    //        dynamicServlet.setLoadOnStartup(1);
    //        
    //        FilterRegistration.Dynamic dynamicFilter = context.addFilter("dynamicFilter", DynamicFilter.class);
    //        
    //        context.addListener("com.hotusm.dynamic.DynamicListener");
    
        }
    }

    对于ServletContainerInitializer的方式,是基于SPI来做的,所以我们需要编辑几个文件:

    里面的内容就是我们的实现类

     

    另一方面在springmvc中我们可以使用WebApplicationInitializer的,因为我们可以在spring-web的架包下面看到:

    里面的内容是:

    其中的类实现有这样一句的代码:

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

    表示的就是凡是实现或者继承WebApplicationInitializer的都会被加载

    @HandlesTypes指定的类的子类和本类都会传进来。(onStartup的第一个参数)

    ServletContext 为动态配置 Servlet 增加了如下方法:

    • ServletRegistration.Dynamic addServlet(String servletName,Class<? extends Servlet> servletClass)
    • ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
    • ServletRegistration.Dynamic addServlet(String servletName, String className)
    • <T extends Servlet> T createServlet(Class<T> clazz)
    • ServletRegistration getServletRegistration(String servletName)
    • Map<String,? extends ServletRegistration> getServletRegistrations()

    其中前三个方法的作用是相同的,只是参数类型不同而已;通过 createServlet() 方法创建的 Servlet,通常需要做一些自定义的配置,然后使用 addServlet() 方法来将其动态注册为一个可以用于服务的 Servlet。两个 getServletRegistration() 方法主要用于动态为 Servlet 增加映射信息,这等价于在 web.xml( 抑或 web-fragment.xml) 中使用 <servlet-mapping> 标签为存在的 Servlet 增加映射信息。

    以上 ServletContext 新增的方法要么是在 ServletContextListener 的 contexInitialized 方法中调用,要么是在 ServletContainerInitializer 的 onStartup() 方法中调用。

    ServletContainerInitializer 也是 Servlet 3.0 新增的一个接口,容器在启动时使用 JAR 服务 API(JAR Service API) 来发现 ServletContainerInitializer 的实现类,并且容器将 WEB-INF/lib 目录下 JAR 包中的类都交给该类的 onStartup() 方法处理,我们通常需要在该实现类上使用 @HandlesTypes 注解来指定希望被处理的类,过滤掉不希望给 onStartup() 处理的类

  • 相关阅读:
    redis集群登陆
    锁机制
    关系型数据库事务遵循ACID原则
    前端之Css
    Python之操作redis数据库
    前端之HTML
    Excel之批量改变特定字体颜色(转载)
    jmeter之批量修改请求路径
    Python之time模块
    Python之os模块
  • 原文地址:https://www.cnblogs.com/zr520/p/6106692.html
Copyright © 2020-2023  润新知