• [SpringMVC笔记] SpringMVC-02-bean加载控制


    SpringMVC-02-bean加载控制

    1、Spring 配置类排除加载 SpringMVC 的 bean

    SpringMVC 通常只需要加载 controller 包内的 bean,而 Spring 需要加载 dao 和 service 包内的 bean,为了省事,Spring 配置类经常设置扫描的包为一个大范围的包(包含 dao 和 service 在内的包),此时 Spring 会错误或者多余地加载到 controller 包内的 bean

    使 Spring 排除加载 SpringMVC 的 bean 一般有两种方法

    • 方法 1:扫描包时精确扫描需要的包,而不用大范围的扫描
    • 方法 2:大范围扫描,但是将不需要的 bean 过滤掉

    方法 1 示例:

    @Configuration
    // 使 Spring 只扫描 dao 与 service 包
    @ComponentScan({"com.mzz.dao", "com.mzz.service"})
    public class SpringConfig {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方法 2:在 @ComponentScan 注解中可以设置 excludeFilters 属性排除掉 不需要的 bean,excludeFilters 属性的值是一个 Filter 注解,这个注解也在 ComponentScan 内,需要设置 type(过滤类型) 和 classes

    下面的示例表示 Spring 的扫描范围为 com.mzz 但是按注解类型过滤掉所有注解了 @Controller 的 bean

    @Configuration
    @ComponentScan(value = "com.mzz",
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,   // 按照 注解 来进行过滤
                classes = {Controller.class}    // 过滤所有注解了 @Controller 的 bean
        )
    )
    public class SpringConfig {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    由于 Filter 注解中 type 的默认值就是 FilterType.ANNOTATION,所以上面的代码可以简写成这样:

    @Configuration
    @ComponentScan(value = "com.mzz",
        excludeFilters = @ComponentScan.Filter({Controller.class})
    )
    public class SpringConfig {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    [补充]

    当 Spring 和 SpringMVC 的配置类同时存在时,上述的方法二可能不会生效,原因是 Spring 进行大范围扫描时可以扫描到 SpringMVC 的配置类,于是 SpringMVC 中的 bean 也被加载到 Spring 中

    此时也有两种解决方法
    一是将 SpringMVC 的配置类移动到 Spring 扫描不到的包下(比如 com 包下)
    二是 Spring 过滤时也将 SpringMVC 的配置类过滤掉,SpringMVC 的配置类会注解 @Configuration 和 @ComponentScan,可以对其进行过滤

    @Configuration
    @ComponentScan(value = "com.mzz",
            excludeFilters = @ComponentScan.Filter({Controller.class, ComponentScan.class})
    )
    public class SpringConfig {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、Servlet 容器配置类简洁开发

    public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {
        // 加载 springMVC 容器配置
        @Override
        protected WebApplicationContext createServletApplicationContext() {
            AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
            ctx.register(SpringMvcConfig.class);
            return ctx;
        }
        
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
        // 加载 spring 容器配置
        @Override
        protected WebApplicationContext createRootApplicationContext() {
            AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
            ctx.register(SpringConfig.class);
            return ctx;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    上面的类继承自 AbstractDispatcherServletInitializer 抽象类,改为继承 AbstractAnnotationConfigDispatcherServletInitializer 抽象类。则只需将配置类 class 返回即可,而不需要手动创建 Context,如下

    public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
        
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{SpringConfig.class};
        }
        // 加载 springMVC 容器配置
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringMvcConfig.class};
        }
        
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    视频链接:https://www.bilibili.com/video/BV1Fi4y1S7ix?p=46

  • 相关阅读:
    写着简单跑着又快的数据库语言SPL
    电大搜题——搜索难题
    2022-08-08 mysql慢SQL-Q18-10GB数据量-mysql/innodb测试
    带433遥控紫外线照明灯触摸芯片-DLT8SA20A-杰力科创
    瑞萨单片机学习:RA4M3单片机 BOOTloader升级 跳转到主程序 主程序无法执行问题
    @Value的注入与静态注入 与 组件中静态工具类的注入
    二维数组案例
    在两个有序数组中找整体第k小的数
    BPR贝叶斯个性化推荐算法—推荐系统基础算法(含python代码实现以及详细例子讲解)
    win11 无法登录微软账号
  • 原文地址:https://blog.csdn.net/Cey_Tao/article/details/126344686