【SpringMVC】<context:include-filter>和<context:exclude-filter>

本文介绍了如何通过配置ApplicationContext.xml和spring-mvc.xml实现组件扫描,分别管理业务逻辑和控制器组件。通过&lt;context:component-scan&gt;标签指定包路径,并使用&lt;context:exclude-filter&gt;排除特定类型的类。

ApplicationContext.xml和spring-mvc.xml分开配置,各司其职。


在ApplicationContext.xml中配置:

<context:component-scan base-package="com.practise">
	<context:exclude-filter type="regex" expression="com.practise.controller"/>
</context:component-scan>

如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者。

其中,<context:exclude-filter>的type可以为下面的值:

</pre></p><p>annotatioin: 标识了某个annotation的类。例如,<span style="background-color: rgb(240, 240, 240);"><context:exclude-filter type="regex" expression="</span><span style="color: rgb(0, 0, 255);">org.springframework.stereotype.Controller</span><span style="background-color: rgb(240, 240, 240);">"/>.</span></p><p>regre: 匹配类全名的正则表达式。</p><p>assignable:a class (or interface) that the  target components are assignable to (extend/implement)。</p><p>assignable:an AspectJ type pattern expression to be matched by the target components。</p><p>assignable:a custom implementation of the org.springframework.core.type.TypeFilter interface。</p><p></p><p>在spring-mvc.xml中配置:</p><p><pre name="code" class="html"><context:component-scan base-package="com.practise.controller" />

同时,也可以将properties的配置文件分开配置。



<think> 我们正在讨论SpringSpringMVC的父子容器关系。根据引用内容,可以总结以下几点关键信息: 1. **父子容器关系存在性**:Spring作为父容器,SpringMVC作为子容器[^1][^2][^3]。 2. **可见性规则**: - 父容器(Spring)中的Bean对子容器(SpringMVC)可见(子容器可以访问父容器的Bean)[^3][^4]。 - 子容器中的Bean对父容器不可见(父容器不能访问子容器的Bean)[^3]。 3. **容器层级作用**:当在子容器中查找Bean时,如果找不到,会委派给父容器查找[^4]。 4. **包扫描配置问题**:由于这种层级关系,包扫描配置不当会导致Bean重复创建或无法注入的问题[^2][^5]。 ### 详细解析父子容器关系 #### 1. **容器结构** 在典型的Spring+SpringMVC项目中: - **父容器(Root WebApplicationContext)**: - 由`ContextLoaderListener`创建(通常在`web.xml`中配置)。 - 负责加载业务层服务层的Bean(如`@Service`, `@Repository`)[^5]。 - 配置文件示例:`applicationContext.xml`。 - **子容器(Servlet WebApplicationContext)**: - 由`DispatcherServlet`创建(每个`DispatcherServlet`有自己的子容器)。 - 负责加载控制器、视图解析器等Web层Bean(如`@Controller`)[^5]。 - 配置文件示例:`springmvc-servlet.xml`。 #### 2. **Bean查找机制** - **子容器查找顺序**: ```mermaid graph LR A[子容器查找Bean] --> B{是否存在?} B -->|是| C[返回Bean] B -->|否| D[委派给父容器查找] D --> E{父容器是否存在?} E -->|是| F[返回父容器的Bean] E -->|否| G[返回null] ``` 这一机制解释了为什么Controller可以注入Service,但Service无法注入Controller[^3][^4]。 #### 3. **配置示例及常见问题** - **错误配置**: - 如果在父容器子容器中都扫描了同一个包(如`com.xxx.service`),会导致: - 父容器创建Service Bean。 - 子容器再次创建相同的Service Bean(重复创建,浪费资源)。 - 可能因重复Bean导致冲突[^2][^5]。 - **正确配置**(官方推荐): - **父容器**扫描:服务层、数据层(排除`@Controller`): ```xml <!-- applicationContext.xml --> <context:component-scan base-package="com.xxx"> <exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> ``` - **子容器**扫描:只包含控制器(避免重复扫描): ```xml <!-- springmvc-servlet.xml --> <context:component-scan base-package="com.xxx.controller" use-default-filters="false"> <include-filter type="annotation" expression="org.springframework.web.bind.annotation.Controller"/> </context:component-scan> ``` 确保各层Bean仅由对应容器加载[^5]。 #### 4. **设计原理与优势** - **解耦**:父子容器分离了业务逻辑(Service/DAO)Web逻辑(Controller),符合分层架构。 - **灵活性**:支持多`DispatcherServlet`共享父容器的Service Bean(如REST APIWeb模块共存)。 - **安全隔离**:避免Web层Bean意外注入业务层。 ### 总结 SpringSpringMVC的父子容器关系是Spring整合Web应用的核心设计,其核心规则是:**子容器可访问父容器的Bean,反之则不可**。正确配置包扫描是避免Bean冲突的关键,官方推荐按层隔离扫描范围[^2][^5]。这一机制既保障了依赖注入的正确性,又实现了架构分层。 §§相关问题§§ 1. 如何在多模块项目中配置Spring父子容器? 2. 父子容器机制如何影响Spring Security的配置? 3. 如果ControllerService定义在同一个包中,如何避免重复扫描? [^1]: 引用自 探究SpringSpringMVC父子容器关系。 [^2]: 引用自 SpringSpringMVC父子容器关系。 [^3]: 引用自 Spring容器关系说明。 [^4]: 引用自 spring与springmvc父子容器。 [^5]: 引用自 springspringmvc父子容器的关系。 </think> ### Spring 与 SpringMVC 父子容器关系详解 #### 一、核心关系原理 Spring SpringMVC 采用**父子容器架构**,这是多模块 Web 应用的核心设计: 1. **层级关系**: - Spring 容器作为**父容器**(Root WebApplicationContext- SpringMVC 容器作为**子容器**(Servlet WebApplicationContext- 父子容器形成树状结构:$$ \text{Spring父容器} \rightarrow \text{SpringMVC子容器} $$ 2. **Bean 可见性规则**: - 子容器可访问父容器的 Bean ✅ (如 Controller 可注入 Service) - 父容器**不可见**子容器的 Bean ❌ (如 Service 无法注入 Controller)[^3][^4] 3. **Bean 查找机制**: ```mermaid graph LR A[子容器查找Bean] --> B{是否存在?} B -->|是| C[返回Bean] B -->|否| D[委派父容器查找] D --> E{父容器存在?} E -->|是| F[返回父容器Bean] E -->|否| G[返回null] ``` #### 二、配置实现方式 通过 `web.xml` 配置体现层级关系: ```xml <!-- 父容器初始化 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 子容器初始化 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springmvc-servlet.xml</param-value> </init-param> </servlet> ``` #### 三、包扫描的正确配置 避免 Bean 重复创建依赖注入失效: ```xml <!-- 父容器配置 (applicationContext.xml) --> <context:component-scan base-package="com.example.service"> <exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 子容器配置 (springmvc-servlet.xml) --> <context:component-scan base-package="com.example.controller" use-default-filters="false"> <include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> ``` ▸ **关键点**:父容器排除 `@Controller`,子容器仅包含 `@Controller`[^5] #### 四、设计优势与典型问题 1. **优势**: - 分层解耦:业务层(Service/DAO)与 Web 层(Controller)分离 - 资源复用:多个 DispatcherServlet 可共享父容器 Bean - 安全隔离:防止 Web 层 Bean 污染业务层 2. **常见问题**: - **循环依赖**:Service 试图注入 Controller 导致失败 - **扫描冲突**:父子容器重复扫描同一包导致 Bean 重复创建 - **AOP 失效**:父容器无法拦截子容器管理的 Bean #### 五、典型应用场景 1. **多模块项目**: ``` ├── 父容器 │ ├── 核心服务模块 │ └── 数据访问模块 └── 子容器 ├── Web 模块1(REST API) └── Web 模块2(后台管理) ``` 2. **微服务网关**:多个 DispatcherServlet(如 /api/*, /admin/*)共享业务服务 ### 总结 Spring 父子容器通过**层级隔离**实现了架构分层,其核心规则是: $$ \text{子容器可见父容器内容} \quad \text{vs} \quad \text{父容器不可见子容器内容} $$ 正确配置包扫描范围层级职责是避免冲突的关键[^1][^2]。在微服务架构中,此模式逐渐被 Spring Boot 的单一容器替代,但在传统企业级应用中仍有重要价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值