加载bean | Servlet配置类优化
- 一、加载 bean
- 1、哪些 bean 需要被加载,被谁加载?
- 2、如何区分加载内容?
- 二、Servlet 配置类优化
- 在之前的 Spring 相关技术的学习过程中,我们涉及到了 Spring 配置类(SpringConfig),该配置类会对数据访问层(dao 包或 mapper 包)、业务逻辑层(service 层)等的 bean 对象进行管理。
- 学了 SpringMVC 后,又接触到了新的领域——表示层(controller 包),那么该层应该由谁来管理呢?很明显,肯定是需要由 SpringMVC 的配置类(SpringMvcConfig)进行管理啊。
- 那么问题来了,这两个配置类都是通过使用 @ComponentScan 注解来完成包的扫描工作,如何区分他们分别都需要加载哪些内容呢?
一、加载 bean
1、哪些 bean 需要被加载,被谁加载?
- SpringMVC 的配置类负责加载表现层,即我们项目中常写的 Controller 。
- Spring 的配置类负责加载数据访问层(即 dao 或 mapper)和业务逻辑层(即 service)。
2、如何区分加载内容?
- 对于 SpringMVC 的配置类,只需加载 Controller 即可。
@Configuration
@ComponentScan("qdxorigin.controller")
public class SpringMvcConfig {
}
- 对于 Spring 配置类,我们可以有两种方式扫描包,用于避免加载 Controller 相关类。
- 方式一:精准扫描包。
@Configuration
@ComponentScan({"qdxorigin.mapper","qdxorigin.service"})
public class SpringConfig {
}
- 方式二:扫描一个大的范围,再使用 excludeFilters 属性去掉和 Controller 相关的类。
@Configuration
@ComponentScan(
value = "qdxorigin",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
- value 指定扫描包范围
- excludeFilters 设置在加载扫描包时,排除在外的过滤规则。
- type 设置排除规则,一共有5种。
- ANNOTATION:按照注解排除。
- ASSIGNABLE_TYPE:按照指定的类型过滤。
- ASPECTJ:按照Aspectj表达式排除,基本不用。
- REGEX:按照正则表达式排除。
- CUSTOM:按照自定义规则排除。
- classes 设置排除的具体类。
二、Servlet 配置类优化
- 在 SpringMVC 入门案例 一文中,我们使用传统的方式手动进行了 Servlet 配置类的编写,传统方式如下:
public class ServletConfig extends AbstractDispatcherServletInitializer {
// 加载SpringMVC配置类
@Override
protected WebApplicationContext createServletApplicationContext() {
// 初始化对象
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
// 加载SpringMVC配置类
context.register(SpringMvcConfig.class);
return context;
}
// 设置SpringMVC需要处理的请求映射路径
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
// 加载Spring配置类
@Override
protected WebApplicationContext createRootApplicationContext() {
// 初始化对象
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
// 加载SpringMVC配置类
context.register(SpringConfig.class);
return context;
}
}
- 发现在加载配置类时,有许多代码都是重复的。
- SpringMVC 也提供了一种更为简便的方式,优化方式如下:
public class ServletConfig2 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[]{"/"};
}
// 处理乱码问题
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setEncoding("UTF-8");
return new Filter[]{cef};
}
}
- 该方式和传统方式相比,首先继承的类发生了变化,传统方式继承的是 AbstractDispatcherServletInitializer ,而优化后直接继承了 AbstractAnnotationConfigDispatcherServletInitializer 。
- 上述优化方式直接返回配置类就行,无需再手动创建 AnnotationConfigWebApplicationContext 对象,手动 register 加载配置类。
- 在 SpringMVC 的开发过程中,我们所涉及到的手动编写 Servlet 配置类,一般只涉及上面部分内容,在需要的时候可以直接复制使用。