Spring MVC Bean Loading Control

Let’s review the packages we generally write about:

  • The configuration class is stored in the config directory, and the configuration classes written are:
    • ServletContainersInitConfig
    • SpringConfig
    • SpringMvcConfig
    • JdbcConfig
    • MybatisConfig
  • The controller directory stores the controller class of SpringMVC
  • The service directory stores the service interface and implementation class
  • The dao directory stores the dao/Mapper interface

bean loading control

It is well known that classes such as controller, service and dao need to be managed by the container as bean objects:

  • SpringMVC loads its related beans (presentation layer beans), which are classes under the controller package
  • Spring-controlled beans
    • Business bean (Service)
    • Functional beans (DataSource, SqlSessionFactoryBean, MapperScannerConfigurer, etc.)

As shown below:
sample graph

In fact, it is very simple. We only need to SpringMvcConfiguse annotations in the configuration class of SpringMVC @ComponentScan, and we only need to set its scanning range to the controller.

insert image description here

But a new problem arises, because SpringConfigthe annotation is used in the Spring configuration class @ComponentScan, the controller is actually included in the scope of the scan at that time
insert image description here

From the perspective of the package structure, Spring has already scanned the controller class of SpringMVC, soBecause of the different functions, how to avoid Spring wrongly loading beans into SpringMVCLet's continue reading.

Concrete operation

To solve that, we can easily think of a solution: exclude the beans controlled by SpringMVC when loading the beans controlled by Spring.

  • Method 1: The bean loaded by Spring sets the scanning range to a precise range, such as service package, dao package, etc.
  • Method 2: The bean loaded by Spring sets the scan range to com.itheima, and excludes the bean in the controller package
  • Method 3: Do not distinguish between Spring and SpringMVC environments, and load them into the same environment ]

Let's take a look at an example, take the following project structure as an example:
insert image description here

First quietly give everyone the same solution
insert image description here

Option One

Modify the Spring configuration class and set the scanning range to the precise range.

@Configuration
@ComponentScan({
    
    "com.taro.service","com.taro.dao"})
public class SpringConfig {
    
    
}

Of course, this example shows that you can precisely specify the corresponding package structure for Spring to scan. When actually doing development,Dao is finally handed over to MapperScannerConfigurerthe object for scanning and processing, we only need to scan it to the service package.Of course it still is 推荐推荐推荐扫描一下的.

Option II

Method 2: Modify the Spring configuration class, set the scanning range to com.iheima, and exclude the beans in the controller package

@Configuration
@ComponentScan(value="com.taro",
    excludeFilters=@ComponentScan.Filter(
    	type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)
public class SpringConfig {
    
    
}

Remember the @Configuration annotation, as we mentioned before, the class Spring that appears in it will scan it and load the bean when scanning

@Configuration//这里这里这里
@ComponentScan("com.taro.controller")
public class SpringMvcConfig {
    
    
}

The next step is to introduce the attributes we wrote:

  • excludeFilters attribute: set the exclusion filtering rules when scanning and loading beans
  • type attribute: set the exclusion rules, currently use the annotation type when the bean is defined to exclude
    • ANNOTATION: exclude by annotation
    • ASSIGNABLE_TYPE: filter according to the specified type
    • ASPECTJ: Excluded according to Aspectj expression, basically not used
    • REGEX: exclude by regular expression
    • CUSTOM: Exclude according to custom rules
  • classes attribute: set the specific annotation class to be excluded, and the current setting excludes the beans defined by @Controller

Of course, with the Spring configuration class, we need to modify ServletContainersInitConfig if we want to load it when the tomcat server starts. Remember what we wrote before?

public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    
    
    protected WebApplicationContext createServletApplicationContext() {
    
    
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    protected WebApplicationContext createRootApplicationContext() {
    
    
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
    protected String[] getServletMappings() {
    
    
        return new String[]{
    
    "/"};
    }

}

Now that the atmosphere is here, it’s embarrassing if it’s not simple;

//web配置类简化开发,仅设置配置类类名即可
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    

    protected Class<?>[] getRootConfigClasses() {
    
    
        return new Class[]{
    
    SpringConfig.class};
    }

    protected Class<?>[] getServletConfigClasses() {
    
    
        return new Class[]{
    
    SpringMvcConfig.class};
    }

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

Let’s feel the intuitive comparison:
insert image description here
they are father and son. . .

Guess you like

Origin blog.csdn.net/weixin_45696320/article/details/130250071