zoukankan      html  css  js  c++  java
  • 重新学习Spring注解——servlet3.0

    53、servlet3.0-简介&测试

    54、servlet3.0-ServletContainerInitializer

    55、servlet3.0-ServletContext注册三大组件

    1、Servlet容器启动会扫描,当前应用里面每一个jar包的
        ServletContainerInitializer的实现
    2、提供ServletContainerInitializer的实现类;
        必须绑定在,META-INF/services/javax.servlet.ServletContainerInitializer
        文件的内容就是ServletContainerInitializer实现类的全类名;
    
    总结:容器在启动应用的时候,会扫描当前应用每一个jar包里面
    META-INF/services/javax.servlet.ServletContainerInitializer
    指定的实现类,启动并运行这个实现类的方法;传入感兴趣的类型;
    
    
    ServletContainerInitializer;
    @HandlesTypes;
    //容器启动的时候会将@HandlesTypes指定的这个类型下面的子类(实现类,子接口等)传递过来;
    //传入感兴趣的类型;
    @HandlesTypes(value={HelloService.class})
    public class MyServletContainerInitializer implements ServletContainerInitializer {
    
        /**
         * 应用启动的时候,会运行onStartup方法;
         * 
         * Set<Class<?>> arg0:感兴趣的类型的所有子类型;
         * ServletContext arg1:代表当前Web应用的ServletContext;一个Web应用一个ServletContext;
         * 
         * 1)、使用ServletContext注册Web组件(Servlet、Filter、Listener)
         * 2)、使用编码的方式,在项目启动的时候给ServletContext里面添加组件;
         *         必须在项目启动的时候来添加;
         *         1)、ServletContainerInitializer得到的ServletContext;
         *         2)、ServletContextListener得到的ServletContext;
         */
        @Override
        public void onStartup(Set<Class<?>> arg0, ServletContext sc) throws ServletException {
            // TODO Auto-generated method stub
            System.out.println("感兴趣的类型:");
            for (Class<?> claz : arg0) {
                System.out.println(claz);
            }
            
            //注册组件  ServletRegistration  
            ServletRegistration.Dynamic servlet = sc.addServlet("userServlet", new UserServlet());
            //配置servlet的映射信息
            servlet.addMapping("/user");        
            
            //注册Listener
            sc.addListener(UserListener.class);
            
            //注册Filter  FilterRegistration
            FilterRegistration.Dynamic filter = sc.addFilter("userFilter", UserFilter.class);
            //配置Filter的映射信息
            filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");        
        }
    }

    56、servlet3.0-与SpringMVC整合分析

    57、springmvc-整合

    58、springmvc-定制与接管SpringMVC

    //Spring的容器不扫描controller;父容器
    @ComponentScan(value="com.atguigu",excludeFilters={
            @Filter(type=FilterType.ANNOTATION,classes={Controller.class})
    })
    public class RootConfig {
    
    }
    //SpringMVC只扫描Controller;子容器
    //useDefaultFilters=false 禁用默认的过滤规则;
    @ComponentScan(value="com.atguigu",includeFilters={
            @Filter(type=FilterType.ANNOTATION,classes={Controller.class})
    },useDefaultFilters=false)
    @EnableWebMvc
    public class AppConfig  extends WebMvcConfigurerAdapter  {
    
        //定制
        
        //视图解析器
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            // TODO Auto-generated method stub
            //默认所有的页面都从 /WEB-INF/ xxx .jsp
            //registry.jsp();
            registry.jsp("/WEB-INF/views/", ".jsp");
        }
        
        //静态资源访问
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            // TODO Auto-generated method stub
            configurer.enable();
        }
        
        //拦截器
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // TODO Auto-generated method stub
            //super.addInterceptors(registry);
            registry.addInterceptor(new MyFirstInterceptor()).addPathPatterns("/**");
        }
    
    }
    @Controller
    public class AsyncController {
        
        
        @ResponseBody
        @RequestMapping("/createOrder")
        public DeferredResult<Object> createOrder(){
            DeferredResult<Object> deferredResult = new DeferredResult<>((long)3000, "create fail...");
                
            DeferredResultQueue.save(deferredResult);
            
            return deferredResult;
        }
        
        
        @ResponseBody
        @RequestMapping("/create")
        public String create(){
            //创建订单
            String order = UUID.randomUUID().toString();
            DeferredResult<Object> deferredResult = DeferredResultQueue.get();
            deferredResult.setResult(order);
            return "success===>"+order;
        }
        
        /**
         * 1、控制器返回Callable
         * 2、Spring异步处理,将Callable 提交到 TaskExecutor 使用一个隔离的线程进行执行
         * 3、DispatcherServlet和所有的Filter退出web容器的线程,但是response 保持打开状态;
         * 4、Callable返回结果,SpringMVC将请求重新派发给容器,恢复之前的处理;
         * 5、根据Callable返回的结果。SpringMVC继续进行视图渲染流程等(从收请求-视图渲染)。
         * 
         * preHandle.../springmvc-annotation/async01
            主线程开始...Thread[http-bio-8081-exec-3,5,main]==>1513932494700
            主线程结束...Thread[http-bio-8081-exec-3,5,main]==>1513932494700
            =========DispatcherServlet及所有的Filter退出线程============================
            
            ================等待Callable执行==========
            副线程开始...Thread[MvcAsync1,5,main]==>1513932494707
            副线程开始...Thread[MvcAsync1,5,main]==>1513932496708
            ================Callable执行完成==========
            
            ================再次收到之前重发过来的请求========
            preHandle.../springmvc-annotation/async01
            postHandle...(Callable的之前的返回值就是目标方法的返回值)
            afterCompletion...
            
            异步的拦截器:
                1)、原生API的AsyncListener
                2)、SpringMVC:实现AsyncHandlerInterceptor;
         * @return
         */
        @ResponseBody
        @RequestMapping("/async01")
        public Callable<String> async01(){
            System.out.println("主线程开始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
            
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    System.out.println("副线程开始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
                    Thread.sleep(2000);
                    System.out.println("副线程开始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
                    return "Callable<String> async01()";
                }
            };
            
            System.out.println("主线程结束..."+Thread.currentThread()+"==>"+System.currentTimeMillis());
            return callable;
        }
    
    }
    1、web容器在启动的时候,会扫描每个jar包下的META-INF/services/javax.servlet.ServletContainerInitializer
    2、加载这个文件指定的类SpringServletContainerInitializer
    3、spring的应用一启动会加载感兴趣的WebApplicationInitializer接口的下的所有组件;
    4、并且为WebApplicationInitializer组件创建对象(组件不是接口,不是抽象类)
        1)、AbstractContextLoaderInitializer:创建根容器;createRootApplicationContext();
        2)、AbstractDispatcherServletInitializer:
                创建一个web的ioc容器;createServletApplicationContext();
                创建了DispatcherServlet;createDispatcherServlet();
                将创建的DispatcherServlet添加到ServletContext中;
                    getServletMappings();
        3)、AbstractAnnotationConfigDispatcherServletInitializer:注解方式配置的DispatcherServlet初始化器
                创建根容器:createRootApplicationContext()
                        getRootConfigClasses();传入一个配置类
                创建web的ioc容器: createServletApplicationContext();
                        获取配置类;getServletConfigClasses();
        
    总结:
        以注解方式来启动SpringMVC;继承AbstractAnnotationConfigDispatcherServletInitializer;
    实现抽象方法指定DispatcherServlet的配置信息;
    
    ===========================
    定制SpringMVC;
    1)、@EnableWebMvc:开启SpringMVC定制配置功能;
        <mvc:annotation-driven/>;
    
    2)、配置组件(视图解析器、视图映射、静态资源映射、拦截器。。。)
        extends WebMvcConfigurerAdapter

    59、servlet3.0-异步请求

    @WebServlet(value="/async",asyncSupported=true)
    public class HelloAsyncServlet extends HttpServlet {
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1、支持异步处理asyncSupported=true
            //2、开启异步模式
            System.out.println("主线程开始。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
            AsyncContext startAsync = req.startAsync();
            
            //3、业务逻辑进行异步处理;开始异步处理
            startAsync.start(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("副线程开始。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
                        sayHello();
                        startAsync.complete();
                        //获取到异步上下文
                        AsyncContext asyncContext = req.getAsyncContext();
                        //4、获取响应
                        ServletResponse response = asyncContext.getResponse();
                        response.getWriter().write("hello async...");
                        System.out.println("副线程结束。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
                    } catch (Exception e) {
                    }
                }
            });        
            System.out.println("主线程结束。。。"+Thread.currentThread()+"==>"+System.currentTimeMillis());
        }
    
        public void sayHello() throws Exception{
            System.out.println(Thread.currentThread()+" processing...");
            Thread.sleep(3000);
        }
    }

    60、springmvc-异步请求-返回Callable

    61、springmvc-异步请求-返回DeferredResult

  • 相关阅读:
    WF4.0 基础篇 (十九) Persistence 持久化
    WF是什么系列之 [ WF控制逻辑线路的算法]
    控制3D模型的例子
    企业信息化建设发展报告
    WF是什么系列之 [ WF控制机械手臂 (3D模型) ]
    WF4.0 RC 对比 Beta2 的变化
    企业信息化所面临的问题
    企业应用的SOA时代
    WF4.0 基础篇 (二十三) 范型Activity
    WF4.0 应用篇(三) IActivityTemplateFactory
  • 原文地址:https://www.cnblogs.com/gzhcsu/p/11657579.html
Copyright © 2011-2022 走看看