SpringMVC整合,出现注解没有起作用的情况处理
作者:高效编程
SpringMVC整合注解没有起作用
在spring的applicationContext.xml中配置问题
正确的配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!--启动注解--> <context:annotation-config /> <!-- base-package 注解所在的包根据自己的需要划分注解类使用的范围 --> <context:component-scan base-package="main.com.talkweb"> <!--不再管理Controller 注解 因为它单独给mvc-servler.xml去管理--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> </beans>
明明有启动注解,但有些注解还是没起作用
<!--启动注解--> <context:annotation-config />
后来发现原因是:下面这句作与springMVC的controller注解的排除关注时,把扫描注解的返回局限了
原来 base-package=”main.com.talkweb.Controller”:
!-- base-package 注解所在的包根据自己的需要划分注解类使用的范围 --> <context:component-scan base-package="main.com.talkweb.Controller"> <!--不再管理Controller 注解 因为它单独给mvc-servler.xml去管理--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
现在的包范围 base-package=“main.com.talkweb”:
!-- base-package 注解所在的包根据自己的需要划分注解类使用的范围 --> <context:component-scan base-package="main.com.talkweb"> <!--不再管理Controller 注解 因为它单独给mvc-servler.xml去管理--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
注解方式整合SpringMVC
整合SpringMVC分析
web容器在启动的时候,会扫描每个jar包下的META-INF/services/javax.servlet.ServletContainerInitializer
文件,加载这个文件里面指定的类SpringServletContainerInitializer
spring的应用一启动就会加载WebApplicationInitializer
接口下的所有组件并创建对象
WebApplicationInitializer
接口下有三个抽象类
AbstractContextLoaderInitializer
抽象类:
调用createRootApplicationContext()
方法来创建根容器
AbstractDispatcherServletInitializer
抽象类
调用createServletApplicationContext()
方法创建一个web的IOC容器
调用createDispatcherServlet()
方法创建了DispatchServlet
将创建的DispatchServlet
添加到ServletContext
中
AbstractAnnotationConfigDispatcherServletInitializer
抽象类
使用注解的方式配置的DispatcherServlet
初始化器
该类重写AbstractContextLoaderInitializer
父类的createRootApplicationContext()
方法来创建根容器。调用getRootConfigClasses()
方法传入一个配置类
该类还重写了AbstractDispatcherServletInitializer
父类的createServletApplicationContext()
方法来创建web的IOC容器。获取配置类注册到IOC容器中。
以注解方式来启动SpringMVC,需要继承AbstractAnnotationConfigDispatcherServletInitializer
,然后实现抽象方法指定DispatcherServlet
的配置信息
注解方式整合SpringMVC
自定义容器初始化器
/*web容器启动的时候创建对象,调用方法来初始化容器以及前端控制器*/ public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { /*获取根容器的配置类,相当于Spring的配置文件,用来创建父容器*/ protected Class<?>[] getRootConfigClasses() { return new Class[]{RootConfig.class}; } /*获取web容器的配置类,相当于SpringMVC的配置文件,用来创建子容器*/ protected Class<?>[] getServletConfigClasses() { return new Class[]{AppConfig.class}; } /*获取DispatcherServlet的映射信息*/ protected String[] getServletMappings() { return new String[]{"/"}; } }
子容器配置类
//SpringMVC只扫描Controller,子容器 @ComponentScan(value = "springMVC", includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}) }) public class AppConfig { }
父容器配置类
//Spring的容器不扫描Controller,必须禁用默认的过滤规则才会生效,父容器 @ComponentScan(value = "springMVC", excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}) }, useDefaultFilters = false) public class RootConfig { }
Service
层
@Service public class HelloService { public String sayHello(String name){ return "hello " + name; } }
Controller
层
@Controller public class HelloController { @Autowired HelloService helloService; @ResponseBody @RequestMapping("/hello") public String hello(){ String hello = helloService.sayHello("张三"); return hello; } }
定制SpringMVC
使用@EnableWebMvc
开启SpringMVC定制配置功能,相当于在xml文件中使用<mvc:annotation-driven/>
标签
@ComponentScan(value = {"controller", "service", "config", "springMVC"}, includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}) }, useDefaultFilters = false) @EnableWebMvc public class AppConfig { }
配置组件,包括视图解析器、视图映射、静态资源映射、拦截器等等
@ComponentScan(value = {"controller", "service", "config", "springMVC"}, includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class}) }, useDefaultFilters = false) @EnableWebMvc public class AppConfig extends WebMvcConfigurerAdapter{ //定制视图解析器 @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/views/", ".jsp"); } //定制静态资源访问 @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { /*相当于在xml配置文件中使用<mvc:default-servlet-handler>标签, * 将SpringMVC处理不了的请求交给Tomcat,这样静态资源就可以访问了*/ configurer.enable(); } //定制拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。