当前位置: 首页 > article >正文

Spring MVC中的Controller加载控制与Bean加载控制详解

    Spring MVC默认通过父子容器实现Web层与非Web组件的隔离。但在实际项目中,若未明确控制组件的扫描路径与加载规则,表现层的Controller、业务层的Service与数据层的Repository往往会被“一刀切”地扫描到同一上下文中。例如,业务层的Service被意外注册到Spring MVC的Web上下文中,或数据源DataSource等基础设施Bean被表现层的组件直接依赖。这种混乱的加载方式不仅可能破坏分层架构的纯净性,还会导致事务管理失效、依赖注入冲突,甚至引发性能隐患。

加载控制

关键点:

在标准的 Spring MVC 应用中,存在 两个独立的上下文

上下文类型加载方式典型组件Bean 可见性
根上下文 (Root)ContextLoaderListenerService、Repository、DataSource对 Web 上下文可见
Web 上下文 (Servlet)DispatcherServletController、Interceptor、ViewResolver仅 Web 上下文内部可见
  • 父子关系:Web 上下文是根上下文的子上下文,因此 Web 上下文可以访问根上下文的 Bean,但根上下文无法访问 Web 上下文的 Bean。

  • 隔离性:若未正确分层,Web 上下文将无法获取业务层组件。

方案一:精确扫描

@Configuration
@ComponentScan("com.cc.controller")
public class SpringMvcConfig {
}

 方案二:过滤

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

@Configuration
@ComponentScan(
        value = "com.cc" ,     //明确扫描哪个包 value同等于basePackage
        excludeFilters = @ComponentScan.Filter(    //表示排除哪些包
                type = FilterType.ANNOTATION,
                classes = Controller.class
        ),
        includeFilters = @ComponentScan.Filter(    //表示精确扫描哪些包
                type = FilterType.ANNOTATION,
                classes = {Service.class, Repository.class}
        )
)
public class SpringConfig {
}

测试:首先将spriongMvcConfig中的注解注释,仅让SpringConfig生效。写一个测试类看是否能获取UserController(在扫描SpringConfig时排除了Controller注解(见上面的代码),所以不能获取到):

import com.cc.config.SpringConfig;
import com.cc.controller.UserController;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext a = new AnnotationConfigApplicationContext(SpringConfig.class);
        System.out.println(a.getBean(UserController.class));
        
    }
}

    接着回到SpringConfig,将排除的部分注释,如果能获取到则说明该方法可行:

简化开发 

    回到servlet容器,在springmvc环境和pring加载不同的配置:

public class ServletConfig extends AbstractDispatcherServletInitializer {

    //加载springmvc容器配置
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();
        app.register(SpringMvcConfig.class);
        return app;
    }

    //设置哪些请求归属springMVC处理
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};  //所有请求
    }

    //加载spring容器配置
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();
        app.register(SpringConfig.class);
        return app;
    }
}

    该方法可以从继承AbstractDispatcherServletInitializer换继承AbstractAnnotationConfigDispatcherServletInitializer:

public class ServletConfig 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[]{"/"};
    }
}


http://www.kler.cn/a/584399.html

相关文章:

  • cu118 安装vllm 极简教程 踩坑笔记
  • 信奥赛CSP-J复赛集训(模拟算法专题)(10):P2356 弹珠游戏
  • 本地算力部署大模型详细流程(一)
  • 虚幻引擎入门
  • 玩转云服务器——阿里云操作系统控制台体验测评
  • 游戏引擎学习第154天
  • Hutool RedisDS:Java开发中的Redis极简集成与高阶应用
  • 云原生性能测试全解析:如何构建高效稳定的现代应用?
  • 一文了解JVM的垃圾回收
  • LLMs基础学习(二)涌现能力、Scaling Law 和 幻觉
  • Science Advances 视触觉传感机制的交互装置,可以实时测量来自手不同部位的分布力
  • 《苍穹外卖》SpringBoot后端开发项目核心知识点与常见问题整理(DAY1 to DAY3)
  • 2025年渗透测试面试题总结-阿里巴巴-阿里云安全 一面、三面(题目+回答)
  • 从零构建逻辑回归: sklearn 与自定义实现对比
  • HTML5(Web前端开发笔记第一期)
  • 【ubuntu】——wsl中使用windows中的adb
  • 《深度剖析:鸿蒙系统下智能NPC与游戏剧情的深度融合》
  • 第27周JavaSpringboot 前后端联调
  • 走进Java:类和对象的初步理解
  • latex问题汇总