Detailed explanation of why the Service layer does not perform global package scanning when integrating Spring

1. The parent-child container relationship between Spring and SpringMVC

1. Before asking a question, you must understand a relationship

Generally speaking, when we integrate the two frameworks of spring and SpringMVC, web.xml will be written like this:

<!-- 加载spring容器 -->
  <!-- 初始化加载application.xml的各种配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/application-*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 配置springmvc前端控制器 -->
  <servlet>
    <servlet-name>taotao-manager</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation,
     springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

The first configuration is the initial loaded application file of the Spring container, and then the front controller (DispatchServlet) of SpringMVC. When the DispatchServlet is configured, a new container will be created in the Spring container. In fact, these are two containers, Spring as the parent container and SpringMVC as the child container.
让我们用图来看一下这个父子关系的原理:

Usually we inject the relationship in the project in this order (combined with the diagram): inject Dao in the Service (initialize automatic injection, use @Autowired), and then inject Service in the Controller (initialize automatic injection, use @Autowired),看图,这就意味这作为SpringMVC的子容器是可以访问父容器Spring对象的。

So let me ask you a question. If it's the other way around, can you inject the Controller into the Service?
肯定是不行的啊!(如图,这也说明了父容器是不能调用子容器对象的)

If Dao, Serive, and Controller are all in the Spring container, the above problem is undoubtedly positive, because they are all in one bean and one container.

2. Question: Why can't the global scan be configured in the Service layer in Spring?

For example: the name of my general project in a project is com.shop, and in the configuration applicationContext-service.xml, the package scan code is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" 
    ...../ 此处省略>

    <!-- 扫描包Service实现类 -->
    <context:component-scan base-package="com.shop.service"></context:component-scan>
</beans>

The configuration above is a local scan, not a global scan. Next, let's talk about the reason:
This is related to the parent-child container mentioned above. If we do a global scan, the code is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" 
    ...../ 此处省略>

    <!-- 扫描包Service实现类 -->
    <context:component-scan base-package="com.shop"></context:component-scan>
</beans>

At this time, @Controller , @Service , @Reposity, @Component will be scanned in the Spring container. The picture at this time is as follows:

Combined with the picture, it is equivalent to placing them in a large container 而这时的SpringMVC容器中没有对象,没有对象就没有Controller,所以加载处理器,适配器的时候就会找不到映射对象,映射关系, so on the page, A 404 error will appear.

3. If you don't use the Spring container, can you put all the layers directly into the SpringMVC container?

Of course, if there is no Spring container, we can put all the layers into SpringMVC. Using this container alone is perfectly fine and lightweight.这里看过yijun zhang老师的Java高并发秒杀API视频的小伙伴们都知道,老师说用的就是直接把所有的层次关系都放到了SpringMVC中,并没有用到Spring容器。

4. So why do we use the Spring container and the SpringMVC container jointly in the project?

the answer is:Spring的扩展性,如果要是项目需要加入Struts等可以整合进来,便于扩展框架。如果要是为了快,为了方便开发,完全可以用SpringMVC框架。

5 Conclusion

If we do a global package scan at the Service layer in the project, then springmvc cannot provide services because there is no controller object in the springmvc subcontainer.


Author : time_is_everything 
Link: https://www.imooc.com/article/16155
Source : MOOC

Guess you like

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