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
原文地址:https://www.cnblogs.com/gzhcsu/p/11657579.html
时间: 2024-10-22 18:22:38