耶耶耶耶耶 发表于 2025-3-7 15:07:39

SpringMVC学习(controller层加载控制与(业务、功能)bean加载控制、Web容器

目录
一、SpringMVC、Spring的bean加载控制。
(1)现实开发的包结构条理。
(2)怎样"精准"控制两个容器分别加载各自bean。(分析)
<1>SpringMVC相干bean加载控制。(方法)
<2>Spring相干bean加载控制。(方法)
二、Spring配置类——bean加载控制。
(1)方法一:设定精确范围。
<1>controller层。
<2>Spring配置类。
<3>SpringMVC配置类。
(2)方法二:直接扫描主包(com.xxx),再排除controller包。
<1>排除过滤器(excludeFilters)与包罗过滤器(includeFilters)。
<2>设置过滤规则(type)与过滤范例(classes)。
<3>最终的Spring配置类。
三、Web容器初始化配置类加载Spring情况。
<1>方法createRootApplicationContext()。
<2>Web容器配置类实现AbstractDispatcherServletInitializer类。(bean加载格式)
<3>实现类AbstractAnnotationConfigDispatcherServletInitializer 。(更简单利用)


一、SpringMVC、Spring的bean加载控制。

   (1)现实开发的包结构条理。



[*]在简单的SpringMVC入门案例中:团体项目的核心包结构只有controller层与config层。
[*]SpringMVC学习(入门案例思绪及实现、Web容器初始化与SpringMVC配置类)(2)-CSDN博客


[*]但现实上真正的项目没有这么简单。其项目的重要包结构如下所示:
[*]config目录。包罗Web容器初识化配置类、Spring配置类、SpringMVC配置类。(代替传统开发的XML配置文件)


[*]controller目录。其内部是所有SpringMVC需要加载的bean。


[*]service、dao等目录。其内部都是各种业务bean、功能bean。而这些bean都是需要让Spring加载。
[*]此中Spring需要管理的业务bean(service层)。需要管理的功能bean(第三方bean)如:DataSource(数据源对象)、SqlSessionFactoryBean等等MyBatis相干bean。
https://i-blog.csdnimg.cn/direct/fa8a85a72f394bacb708b68c6351b306.png
(2)怎样"精准"控制两个容器分别加载各自bean。(分析)

<1>SpringMVC相干bean加载控制。(方法)



[*]让controller层的bean被SpringMVC加载控制很轻易做到。——控制SpringMVC加载的bean对应包位于对应的本身项目的controller目录下即可。
https://i-blog.csdnimg.cn/direct/fe5c36381d5e4f169e6af10998e1af5c.png
<2>Spring相干bean加载控制。(方法)



[*]让Spring只加载对应的业务bean、功能bean。而避免加载到SpringMVC管理的bean。
[*]方式一:Spring加载的bean设定扫描范围为com.xxx,再排除掉controller包内的bean。
[*]方式二:Spring加载的bean设定扫描范围为精准范围。就是扫描包设定每层的精确范围:com.xxx.service包、com.xxx.dao包等。
[*]方式三:不区分Spring与springMVC的情况,加载到同一个情况中。
二、Spring配置类——bean加载控制。

   (1)方法一:设定精确范围。



[*]缩小具体包对应的范围。这样就不会扫描到SpringMVC管理的bean地点controller层中。
<1>controller层。



[*]ExampleController类。
package com.hyl.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* 控制器类
*/
//1.使用注解@Controller定义bean
@Controller
public class ExampleController {

    /**
   * 随机写一个处理请求的方法
   * @return 字符串(模仿json数据)
   */
    //设置当前方法操作的访问路径
    @RequestMapping("/save")
    //设置当前操作的返回值类型(如何响应给客户端)
    @ResponseBody
    public String save(){
      //方便测试查看运行结果。
      System.out.println("exampleController save ...");
      return "{'module':'springMVC'}";
    }

}
<2>Spring配置类。

package com.hyl.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

//创建Spring的配置类
//排除加载controller包对应bean,使controller层交给SpringMVC管理

@Configuration
@ComponentScan({"com.hyl.service","com.hyl.dao"})
/*@ComponentScan("com.hyl")*/
public class SpringConfig {
}
<3>SpringMVC配置类。

package com.hyl.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

//创建SpringMVC的配置类,加载controller包对应bean

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


[*]测试类。(App)
package com.hyl.test;

import com.hyl.config.SpringConfig;
import com.hyl.controller.ExampleController;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {

    @Test
    public void test(){
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
      ExampleController exampleController = context.getBean(ExampleController.class);
      System.out.println(exampleController);
    }

}


[*]测试运行结果。无法获取controller层的对应bean。
https://i-blog.csdnimg.cn/direct/5b433d8a1dff46e7bf8df9b7f4d6f63f.png
(2)方法二:直接扫描主包(com.xxx),再排除controller包。



[*]按住ctrl进入注解@ComponentScan查看其内部的可用属性。
<1>排除过滤器(excludeFilters)与包罗过滤器(includeFilters)。

https://i-blog.csdnimg.cn/direct/3d9f7551b0e3475f8d11acef7b32dca6.png
<2>设置过滤规则(type)与过滤范例(classes)。



[*]excludeFilters取值:注解@ComponentScan的Filter。
https://i-blog.csdnimg.cn/direct/9dd0210e9e754196aebf44d5d5b7c681.png


[*]属性type、classes根属地。
https://i-blog.csdnimg.cn/direct/e57f995fba6043d5bd5f059916fc393c.png


[*]过滤规则。分为很多个过滤计谋:FilterType.xxx。(包括按注解过滤规则、用户自界说过滤规则、正则过滤规则等等)
https://i-blog.csdnimg.cn/direct/a8b9ad5f2908408f9e897835536b0142.png


[*]过滤范例。当过滤规则设定为:按注解进行过滤时。就需要再手动指定需要过滤的注解是哪个范例(注解:@Controller),才气完成注解的过滤扫描。
https://i-blog.csdnimg.cn/direct/82070119bf89433c918ecb948d0a6858.png
<3>最终的Spring配置类。



[*]简单说以上利用的目的:当Spring扫描整个包"com.xxx"下所有包时,需要按照注解排除扫描——注解@Controller下标明的bean。
package com.hyl.config;

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

//创建Spring的配置类
//排除加载controller包对应bean,使controller层交给SpringMVC管理

@Configuration
/*@ComponentScan({"com.hyl.service","com.hyl.dao"})*/
@ComponentScan(value = "com.hyl",
      excludeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,
                classes = Controller.class
      )
)
public class SpringConfig {
}


[*]测试类。
package com.hyl.test;

import com.hyl.config.SpringConfig;
import com.hyl.controller.ExampleController;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {

    @Test
    public void test(){
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
      ExampleController exampleController = context.getBean(ExampleController.class);
      System.out.println(exampleController);
    }

}


[*]测试前需要将SpringMVC的配置类的注解@Configuration解释,否则即使在spring配置类中利用了注解拦截扫描,但最终还是会因为该注解自动将bean交给Spring容器管理。
https://i-blog.csdnimg.cn/direct/4c242d3bb286494b85e0721d551f6ce6.png
https://i-blog.csdnimg.cn/direct/ce9565c81eb94152b1a2607cfc2dca89.png


[*]解释@Configuration后,继续获取Controller层的对应bean就会报错。
[*]为了既可以拦截注解生效,又可以让SpringMVC配置类被扫描到,可以将其提到上一级目录大概上上级目录即可。(如:放置com包下,不放在com.xxx下的某个目录)
https://i-blog.csdnimg.cn/direct/a662f78b972846d592b9c38406f61da1.png
三、Web容器初始化配置类加载Spring情况。

   

[*]在SpringMVC的入门案例中。配置Tomcat运行的Web容器初识化启动配置类中,其时只配置了SpringMVC的情况。这次顺手将Spring的情况一起配置了。
https://i-blog.csdnimg.cn/direct/8193a7e913244d729b34c71f7046116f.png
<1>方法createRootApplicationContext()。



[*]createRootApplicationContext()方法作用就是配置Spring的情况,加载Spring配置类。
[*]与加载SpringMVC配置类的利用一模一样。不一样的地方就是修改:配置类.class。
<2>Web容器配置类实现AbstractDispatcherServletInitializer类。(bean加载格式)



[*]这样当服务器启动时,不仅有SpringMVC容器,还有Spring容器。
[*]createServletApplicationContext()——>加SpringMVC容器。
[*]createRootApplicationContext()——>Spring容器。
package com.hyl.config;


import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

//定义一个Servlet容器启动的配置类,在里面加载SpringMVC的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    /**
   *加载SpringMVC配置类
   * @return
   */
    @Override
    protected WebApplicationContext createServletApplicationContext() {
      AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();
      webApplicationContext.register(SpringMvcConfig.class);
      return webApplicationContext;
    }

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

    /**
   * 设置哪些请求归属SpringMVC处理
   * @return
   */

    @Override
    protected String[] getServletMappings() {
      return new String[]{"/"};
    }

}
<3>实现类AbstractAnnotationConfigDispatcherServletInitializer 。(更简单利用)

https://i-blog.csdnimg.cn/direct/b9cf952eb51d4351a0ab57dfd4e1d9d1.png


[*]简化后的Web容器配置类。
package com.hyl.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;


//定义一个Servlet容器启动的配置类,在里面加载SpringMVC、Spring的配置
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

    /**
   *加载Spring配置类(加载Spring容器)
   * @return
   */
    @Override
    protected Class<?>[] getRootConfigClasses() {
      return new Class[]{SpringConfig.class};
    }

    /**
   *加载SpringMVC配置类
   * @return
   */
    @Override
    protected Class<?>[] getServletConfigClasses() {
      return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
      return new String[]{"/"};
    }
}




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: SpringMVC学习(controller层加载控制与(业务、功能)bean加载控制、Web容器