SpringMVC全注解配置学习笔记

  1. 编写根容器配置类
    @Configuration
    @ComponentScan("com.yicj.study.mvc.hello.service")
    public class RootConfig {
    }
    
  2. 编写web容器配置类
    @EnableWebMvc
    @Configuration
    @ComponentScan("com.yicj.study.mvc.hello.controller")
    public class WebConfig {
        @Bean
        public InternalResourceViewResolver viewResolver(){
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver() ;
            viewResolver.setPrefix("/WEB-INF/jsp/");
            viewResolver.setSuffix(".jsp");
            return viewResolver ;
        }
    }
    
  3. 编写WebApplicationInitializer实现类,一般直接继承AbstractAnnotationConfigDispatcherServletInitializer类
    // SpringServletContainerInitializer实现了ServletContainerInitializer接口
    // 在SpringServletContainerInitializer的onStartup方法中会
    public class StarterWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
        // 根容器的配置类
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{RootConfig.class};
        }
        // web容器的配置类
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{WebConfig.class};
        }
        // DispatcherServlet拦截地址
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
        // 指定DispatcherServlet中的filter
        @Override
        protected Filter[] getServletFilters() {
            CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter("UTF-8", true) ;
            return new Filter[]{encodingFilter};
        }
    }
    
  4. 编写业务代码,以及控制层代码
    @Data
    public class User {
        private Integer id ;
        private String name ;
    }
    //
    @Service
    public class UserServiceImpl implements UserService {
        @Override
        public User saveUser(User user) {
            user.setId(1);
            return user ;
        }
    }
    //
    @Controller
    public class HomeController {
        @ResponseBody
        @GetMapping("/hello")
        public String hello(){
            return "hello world" ;
        }
    
        @GetMapping("/helloworld")
        public String helloworld(){
    
            return "helloworld" ;
        }
    }
    
  5. 在webapp/WEB-INF/jsp/ 目录中创建helloworld.jsp
    <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>hello test</title>
    </head>
    <body>
        Hello World!<br/>
    </body>
    </html>
    
  6. 添加依赖
    <!-- 注意这里要写war否则项目可能无法运行-->
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    
  7. Servlet3.x规范利用spi机制,自动加载实现ServletContainerInitializer接口的类,并调用onStartup方法。
  8. SpringServletContainerInitializer根据@HandlesTypes(WebApplicationInitializer.class)进行class筛选。
  9. 在onStartup中调用所有WebApplicationInitializer对象的onStart方法。
  10. SpringServletContainerInitializer代码实现
    @HandlesTypes(WebApplicationInitializer.class)
    public class SpringServletContainerInitializer implements ServletContainerInitializer {
       @Override
       public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)throws ServletException {
       	List<WebApplicationInitializer> initializers = new LinkedList<>();
       	if (webAppInitializerClasses != null) {
       		for (Class<?> waiClass : webAppInitializerClasses) {
       			if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
       					WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
       				try {
       					initializers.add((WebApplicationInitializer)
       					ReflectionUtils.accessibleConstructor(waiClass).newInstance());
       				}
       				catch (Throwable ex) {
       					throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
       				}
       			}
       		}
       	}
       	if (initializers.isEmpty()) {
       		servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
       		return;
       	}
       	servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
       	AnnotationAwareOrderComparator.sort(initializers);
       	for (WebApplicationInitializer initializer : initializers) {
       		initializer.onStartup(servletContext);
       	}
       }
    
    }
    
补充说明
  1. 在嵌入式容器中@WebServlet不会被自动扫描,替代方案可使用@ServletComponentScan解决
    @ServletComponentScan("com.yicj.web.servlet")
    @SpringBootApplication
    public class WebMvcApplication {
    }
    
  2. 在嵌入式容器中ServletContainerInitializer将不会被自动加载,替代方案可使用ServletContextInitializer解决
    @Bean
    public ServletContextInitializer servletContextInitializer(){
       return servletContext ->{
           CharacterEncodingFilter filter = new CharacterEncodingFilter() ;
           FilterRegistration.Dynamic dynamic = servletContext.addFilter("c-filter", filter);
           dynamic.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false,"/");
       } ;
    }
    
  3. 在嵌入式容器中@WebServlet不会被自动扫描,替代方案可使用@ServletRegistrationBean解决
    // ServletRegistrationBean 继承ServletContextInitializer,所以这里与2中效果等同
    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
         ServletRegistrationBean registrationBean =
                 new ServletRegistrationBean(new AsyncServlet(), "/async-servlet") ;
         return registrationBean ;
     }
    
  4. ServletContextInitializer加载的流程
    2.1 ServletWebServerApplicationContext容器刷新方法onRefresh() 调用 createWebServer() 创建Web服务
    2.2 创建容器时,通过getSelfInitializer() =>  getServletContextInitializerBeans() 获取所有的ServletContextInitializer
    2.3 遍历ServletContextInitializer实例并调用onStartup(servletContext)方法
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值