Why are Spring and Spring MVC package scanning separate?

 

    background:

      Recently, when building a new project, I found that some Spring configurations are not well understood. For example, component-scan is clearly configured in the Spring configuration. Why does the Spring MVC configuration file need to be configured? Isn’t this superfluous? Because the previous project was basically developed directly on the existing project or the configuration files of other projects were copied directly, so I didn't pay much attention to this problem. Out of curiosity, I googled it and found that there is a lot of knowledge in this, see below for details. The normal code is as follows:

 

<!-- spring configuration file -->
<context:component-scan base-package="com.xxx.xxx.account.front">
	 <context:exclude-filter type="annotation"
         expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<!-- spring mvc -->	
<context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
	<context:include-filter type="annotation"
        expression="org.springframework.stereotype.Controller" />
</context:component-scan>

    

    test bean

@Service
public class TestService implements InitializingBean {

    @Autowired
    private PersonalAddressAjaxController personalAddressAjaxController;

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("--------------------------------");
    }
}

 

    principle:   

      It turns out that Spring is the parent container, and Spring MVC is the child container. The child container can access the beans of the parent container, but the parent container cannot access the beans of the child container. 

     Specific reference:

      A First Look at the Parent-Child Container Relationship between Spring and SpringMVC

      Why doesn't Spring do global package scanning

      Analysis of container relationship between Spring and SpringMVC

 

    Test 1:  Spring loads all beans, MVC loads Controller

<!-- spring configuration file -->
<context:component-scan base-package="com.xxx.xxx.account.front">
</context:component-scan>

<!-- spring mvc -->	
<context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
	<context:include-filter type="annotation"
        expression="org.springframework.stereotype.Controller" />
</context:component-scan>

    

    Test result: TestService passed, and the interface is displayed normally.

    Reason: The parent container loads all the beans, so the Service can access the Controller. The MVC container looks for the current container by default, and can find the Controller rules with forwarding, so the interface jumps normally.

 

    Test 2: Spring loads all beans, and the MVC container loads nothing

<!-- spring configuration file -->
<context:component-scan base-package="com.xxx.xxx.account.front">
</context:component-scan>

<!-- spring mvc -->	
without

    Test result: TestService passes, and the interface displays 404.

    Reason: The parent container loads all the beans, so the Service can access the Controller. The MVC container looks for the Controller of the current container by default, and it cannot find it, so 404 appears on the interface.

 

   Test 3: Spring loads all beans except Controller , MVC only loads Controller

<!-- spring configuration file -->
<context:component-scan base-package="com.xxx.xxx.account.front">
	 <context:exclude-filter type="annotation"
         expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<!-- spring mvc -->	
<context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
	<context:include-filter type="annotation"
        expression="org.springframework.stereotype.Controller" />
</context:component-scan>

    Test result: The initialization of TestService failed. If the bean is commented out, the interface is normal.

    Cause: The parent container cannot access the beans of the child container.

 

    Test 4: Spring does not load beans, MVC loads all beans

<!-- spring configuration file -->
without

<!-- spring mvc -->	
<context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="true">
</context:component-scan>

    Test result: TestService passed, and the interface is normal.

    Reason: Because all beans are in the subcontainer, the Controller in the current container can also be found, so there is no problem.

 

 

    Question 1: Do singleton beans have one instance or two instances in the parent-child container?

    Answer: It is initialized twice. The Spring container initializes the bean first, and the MVC container initializes the bean, so there should be two beans.

 

    Question 2: Why not scan all beans in the subcontainer?

    A: Many articles on the Internet say that subcontainers do not support AOP, but this is not true. Because there are normally AOP-related configurations configured in the Spring container, if they are all migrated to the MVC configuration file, all beans are in the sub-container, which is equivalent to only one container, so AOP is also implemented. The disadvantage is that it is not conducive to expansion.

    

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326440811&siteId=291194637