(3)案例工作流程
-
启动服务器初始化过程
-
1.服务器启动,执行ServletContainersInitConfig类,初始化web容器功能类似于以前的web.xml
-
2.执行createServletApplicationContext方法,创建了WebApplicationContext对象 该方法加载SpringMVC的配置类SpringMvcConfig来初始化SpringMVC的容器
-
3.加载SpringMvcConfig配置类
-
4.执行@ComponentScan加载对应的bean 扫描指定包及其子包下所有类上的注解,如Controller类上的@Controller注解
-
5.加载UserController,每个@RequestMapping的名称对应一个具体的方法此时就建立 /save 和 save方法的对应关系
-
6.执行getServletMappings方法,设定SpringMVC拦截请求的路径规则/代表所拦截请求的路径规则,只有被拦截后才能交给SpringMVC来处理请求
-
-
单次请求过程
-
1.发送请求 http://localhost/save
-
2.web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理
-
3.解析请求路径/save
-
4.由/save匹配执行对应的方法save()
-
5.上面的第五步已经将请求路径和方法建立了对应关系,通过/save就能找到对应的save方法执行save()
-
6.检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方
-
(4)bean加载控制
-
Spring容器加载的bean和SpringMVC所加载的bean应该单独进行管理,否则spring也能对SpringMVC的bean进行管理
-
Spring容器所管理的bean
-
业务bean(service)
-
功能bean (DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)
-
-
SpringMVC所管理的bean
-
加载其相关bean(表现层bean),也就是controller包下的控制类
-
-
如何避免Spring加载到SpringMVC的bean
-
1.将Spring和SpringMVC的配置类包扫描的路径设定为一个精确的包,如service、dao等
@Configuration @ComponentScan({"com.presentationLayer.controller"}) public class SpringMVCConfig{...} @Configuration @ComponentScan({"com.presentationLayer.dao","com.presentationLayer.service"}) @PropertySource("jdbc.properties") @Import({JdbcConfig.class, MybatisConfig.class}) public class SpringConfig {...}
-
2.在Spring配置类包扫描一个目录下的所有包的同时排除SpringMVC管理的bean所在的包,这里需要满足一个前提条件==》SpringMVCConfig的配置类中不能将扫描controller,否则排除无法生效,这是由于 SpringMvcConfig 上有一个@Configuration注解,也会被Spring扫描到 SpringMvcConfig上又有一个@ComponentScan,把controller类又给扫描进来了
@ComponentScan(value = {"com.presentationLayer"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class))
-
-
-
3.excludeFilters属性:设置扫描加载bean时,排除的过滤规则
-
type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
-
ANNOTATION:按照注解排除
-
ASSIGNABLE_TYPE:按照指定的类型过滤
-
ASPECTJ:按照Aspectj表达式排除,基本上不会用
-
REGEX:按照正则表达式排除
-
CUSTOM:按照自定义规则排除
-
-
classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
-
-
在tomcat服务器启动将Spring的配置类加载,我们需要修改 ServletContainersInitConfig
//加载spring配置类 protected WebApplicationContext createRootApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringConfig.class); return ctx; }
-
对于web容器上述的配置方式,Spring还提供了一种更简单的配置方式,可以不用再去创建 AnnotationConfigWebApplicationContext 对象,不用手动 register 对应的配置类
public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{ protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; } protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMVCConfig.class}; } protected String[] getServletMappings() { return new String[]{"/"}; } }