问题提出:学习Spring技术的时候在config目录下创建了一个配置类SpringConfig
。现在学习SpringMVC技术在config目录下又创建一个SpringMvcConfig
配置类。这两个配置类都需要加载资源,那么它们分别都需要加载哪些内容?
目录结构:
-
config目录存入的是配置类,写过的配置类有:
- ServletContainersInitConfig
- SpringConfig
- SpringMvcConfig
- JdbcConfig
- MybatisConfig
-
controller目录存放的是SpringMVC的controller类
-
service目录存放的是service接口和实现类
-
dao目录存放的是dao/Mapper接口
controller、service和dao这些类都需要被容器管理成bean对象,那么到底是该让SpringMVC加载还是让Spring加载呢?
- SpringMVC加载其相关bean(表现层bean),也就是controller包下的类
- Spring控制的bean
- 业务bean(Service)
- 功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)
如何让Spring和SpringMVC分开加载各自的内容????
在SpringMVC的配置类SpringMvcConfig
中使用注解@ComponentScan
:
在Spring的配置类SpringConfig
中使用注解@ComponentScan
:
解决方式一(不推荐):Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等。
修改SpringConfig
类如下:
@Configuration
@ComponentScan({"com.itheima.service","comitheima.dao"})
public class SpringConfig {
}
解决方式二(推荐):Spring加载的bean设定扫描范围为com.itheima,排除掉controller包中的bean。
修改SpringConfig
类如下:
@Configuration
@ComponentScan(value="com.itheima",
excludeFilters=@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
-
excludeFilters属性:设置扫描加载bean时,排除的过滤规则。
-
type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除:
ANNOTATION
:按照注解排除(常用)- ASSIGNABLE_TYPE:按照指定的类型过滤
- ASPECTJ:按照Aspectj表达式排除,基本上不会用
- REGEX:按照正则表达式排除
- CUSTOM:按照自定义规则排除
-
classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean。
解决方式三(了解):不区分Spring与SpringMVC的环境,加载到同一个环境中。
有了Spring的配置类,要想在tomcat服务器启动将其加载,需要修改ServletContainersInitConfig
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
对于上述的配置方式,Spring还提供了一种更简单的配置方式,可以不用再去创建AnnotationConfigWebApplicationContext
对象,不用手动register
对应的配置类,这种方式可独享比较差:
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}