Java框架Spring MVC理解003spring MVC自身的创建

spring MVC自身的创建

1.整体结构介绍

  springMVC中核心servlet的继承结构:

 

  从结构图中可以看到,servlet的继承结构中一共有5个类。这里来说一下spring中的三个类。

  这三个类直接实现三个接口:EnvironmentCapable、EnvironmentAware和Application-ContextAware。XXXAware在spring里表示对XXX可以感知,通俗点解释就是:如果在某个类里面想要使用spring的一些东西,就可以通过实现XXXAware接口告诉spring,spring看到后就会给你送过来,而接收的方式是通过实现接口唯一的方法set-XXX。

  比如,有一个类想要使用当前的ApplicationContext,那么我们只需要让它实现ApplicationContextAware接口,然后实现接口中唯一的方法void setApplicationContext(ApplicationContext applicationContext)就可以了,spring会自动调用这个方法将applicationContext传给我们,我们只需要接收就可以了。EnvironmentCapable,顾名思义,当然就是具有Environment的能力,也就是可以提供Environment,所以EnvironmentCapable唯一的方法是Environment getEnvironment(),用于实现EnvironmentCapable接口的类,就是告诉spring它可以提供Environment,当spring需要Environment的时候就会调用其getEnvironment方法跟它要。
  了解了Aware和Capable的意思,下面再来看一下ApplicationContext和Environment。前者相信大家都很熟悉了,后者是环境的意思。实际上在HttpServletBean中Environment使用的是Standard-Servlet-Environment(在createEnvironment方法中创建),这里封装了ServletContext,同时还封装了ServletConfig、JndiProperty、系统环境变量和系统属性,这些都封装到了其propertySources属性下。

  为了让大家理解得更深刻,在前面项目的GoController中获取Environment,然后通过调试看一下。首先让GoController实现EnvironmentAware接口,这样spring就会将Environment传给我们,然后在处理请求的方法中加入断点,这样就可以查看spring传进来的内容了。

2.HttpServletBeen

 

  我们知道Servlet创建时可以直接调用无参数的init方法。HttpServletBean的init方法如下:

  可以看到,在HttpServletBean的init中,首先将Servlet中配置的参数使用BeanWrapper设置到DispatcherServle的相关属性,然后调用模板方法initServletBean,子类就通过这个方法初始化。

BeanWrapper:BeanWrapper是Spring提供的一个用来操作JavaBean属性的工具,使用它可以直接修改一个对象的属性。

public class User {
    private String userName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.PropertyValue;

import com.excelib.common.User;

public class BeanWrapperTest {
    
    public static void main(String[] args) {
        User user=new User();
        BeanWrapper bw=PropertyAccessorFactory.forBeanPropertyAccess(user);
        bw.setPropertyValue("userName","张安");
        System.out.println(user.getUserName());
        PropertyValue prvalue=new PropertyValue("userName", "六六");
        bw.setPropertyValue(prvalue);
        System.out.println(user.getUserName());
    }
}

这个例子首先新建了一个User对象,其次使用PropertyAccessorFactory封装成Bean-Wrapper对象,这样就可以使用了。

3.FrameworkServlet

首先看源码:他继承了httpservletBean,实现了ApplicationContextAware

他的初始化入口:

这里可以查看initWebApplicationContext()源码,他主要做了三件事。

①获取spring的根容器rootContext

②设置webApplicationContext并根据情况调用onrefresh()

③讲webApplicatiuonContext设置到servletContest中

4.DispatcherServlet

有兴趣的可以研究一下 源码。

5.总结

  通过源码,了解Spring MVC自身的创建过程,Spring MVC中Servlet一共有三个层次,分别是HttpServletBean、FrameworkServlet和DispatcherServlet。HttpServletBean直接继承自Java的HttpServlet,其作用是将Servlet中配置的参数设置到相应的属性;FrameworkServlet初始化了WebApplicationContext,DispatcherServlet初始化了自身的9个组件。
  FrameworkServlet初始化WebApplicationContext一共有三种方式,过程中使用了Servlet中配置的一些参数。
整体结构非常简单——分三个层次做了三件事,但具体实现过程还是有点复杂的。这其实也是spring的特点:结构简单,实现复杂。结构简单主要是顶层设计好,实现复杂的主要是提供的功能比较多,可配置的地方也非常多。当然,正是因为实现复杂,才让Spring MVC使用起来更加灵活,这一点在后面会有更深刻的体会。自己需要静下心来对照着源代码耐心地去看,我现在还有很多地方不是很明白,不在实际操作上应用不会了解很透彻,希望读者可以多留言交流。

原文地址:https://www.cnblogs.com/yulibo/p/9011414.html