interface21的研究

       昨晚有人提到spring的最初版本interface21,Spring的源码太复杂,跟着看有点晕,所以决定跟着人家的博客,先走一下interface21中DispatcherServlet初始化的流程。看完了从人家的编码风格和逻辑跳转,收获满满。

1:首先,执行DispatcherServlet的父类HttpServletBean的init方法;

public final void init() throws ServletException {
        this.identifier = "Servlet with name '" + getServletConfig().getServletName() + "' ";

        logger.info(getIdentifier() + "entering init...");

        // Set bean properties
        try {
            //servlet 初始化属性值
            PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), requiredProperties);
            BeanWrapper bw = new BeanWrapperImpl(this);
            //为BeanWrapperImpl设置属性。
            bw.setPropertyValues(pvs);
            logger.debug(getIdentifier() + "properties bound OK");

            // Let subclasses do whatever initialization they like
            initServletBean();
            logger.info(getIdentifier() + "configured successfully");
        } catch (BeansException ex) {
            String mesg = getIdentifier() + ": error setting properties from ServletConfig";
            logger.error(mesg, ex);
            throw new ServletException(mesg, ex);
        } catch (Throwable t) {
            // Let subclasses throw unchecked exceptions
            String mesg = getIdentifier() + ": initialization error";
            logger.error(mesg, t);
            throw new ServletException(mesg, t);
        }
    }

2. 获取Servlet的初始化参数,创建BeanWrapperImpl 实例,设置属性值;

3.执行HttpServletBean的子类FrameworkServlet的initServletBean方法;

 protected final void initServletBean() throws ServletException {
        long startTime = System.currentTimeMillis();
        logger.info("Framework servlet '" + getServletName() + "' init");
        this.webApplicationContext = createWebApplicationContext();
        initFrameworkServlet();
        long elapsedTime = System.currentTimeMillis() - startTime;
        logger.info("Framework servlet '" + getServletName() + "' init completed in " + elapsedTime + " ms");
    }

 

4.调用FrameworkServlet的createWebApplicationContext方法.

 private WebApplicationContext createWebApplicationContext() throws ServletException {
        getServletContext().log("Loading WebApplicationContext for servlet '" + getServletName() + "'");
        ServletContext sc = getServletConfig().getServletContext();
        WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(sc);
        String namespace = getNamespace();
        //这段代码风格上有点东西
        WebApplicationContext waca = (this.contextClass != null) ?
                instantiateCustomWebApplicationContext(this.contextClass, parent, namespace) :
                new XmlWebApplicationContext(parent, namespace);
        logger.info("Loading WebApplicationContext for servlet '" + getServletName() + "': using context class '" + waca.getClass().getName() + "'");
        waca.setServletContext(sc);

        if (this.publishContext) {
            // Publish the context as a servlet context attribute
            String attName = getServletContextAttributeName();
            sc.setAttribute(attName, waca);
            logger.info("Bound context of servlet '" + getServletName() + "' in global ServletContext with name '" + attName + "'");
        }
        return waca;
    }

5.进入createWebApplicationContext方法,从ServletContext的属性中获取WebApplicationContext,该上下文是由ContextLoaderListener加载的。

6.执行子上下文XmlWebApplicationContext的waca.setServletContext方法,去加载petclinic-servlet.xml配置文件(国际化,主题,HandlerMapping、HandlerAdapter、视图解析等相关配置)。

7.将该子上下文设置到ServletContext属性中

8.进入DispatcherServlet类的initFrameworkServlet方法,主要执行一些初始化工作

 protected void initFrameworkServlet() throws ServletException {
        initLocaleResolver();
        initThemeResolver();
        initHandlerMappings();
        initHandlerAdapters();
        initViewResolver();
    }

 

9.国际化相关:执行initLocaleResolver方法,从上下文中获取localeResolver bean,没有则使用默认AcceptHeaderLocaleResolver

    private void initLocaleResolver() throws ServletException {
        try {
            this.localeResolver = (LocaleResolver) getWebApplicationContext().getBean(LOCALE_RESOLVER_BEAN_NAME);
            logger.info("Loaded locale resolver [" + this.localeResolver + "]");
        } catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default
            this.localeResolver = new AcceptHeaderLocaleResolver();
            logger.info("Unable to locate locale resolver with name '" + LOCALE_RESOLVER_BEAN_NAME + "': using default [" + this.localeResolver + "]");
        } catch (BeansException ex) {
            // We tried and failed to load the LocaleResolver specified by a bean
            throw new ServletException("Fatal error loading locale resolver with name '" + LOCALE_RESOLVER_BEAN_NAME + "': using default", ex);
        }
    }

10.主题相关:执行initThemeResolver方法,从上下文中获取themeResolver bean,没有则使用默认FixedThemeResolver

private void initThemeResolver() throws ServletException {
        try {
            this.themeResolver = (ThemeResolver) getWebApplicationContext().getBean(THEME_RESOLVER_BEAN_NAME);
            logger.info("Loaded theme resolver [" + this.themeResolver + "]");
        } catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default
            this.themeResolver = new FixedThemeResolver();
            logger.info("Unable to locate theme resolver with name '" + THEME_RESOLVER_BEAN_NAME + "': using default [" + this.themeResolver + "]");
        } catch (BeansException ex) {
            // We tried and failed to load the ThemeResolver specified by a bean
            throw new ServletException("Fatal error loading theme resolver with name '" + THEME_RESOLVER_BEAN_NAME + "': using default", ex);
        }
    }

11.执行initHandlerMappings方法,从上下文中获取HandlerMapping类型的bean,没有则使用默认BeanNameUrlHandlerMapping

 private void initHandlerMappings() throws ServletException {
        this.handlerMappings = new ArrayList();

        // Find all HandlerMappings in the ApplicationContext
        String[] hms = getWebApplicationContext().getBeanDefinitionNames(HandlerMapping.class);
        for (int i = 0; i < hms.length; i++) {
            initHandlerMapping(hms[i]);
            logger.info("Loaded handler mapping [" + hms[i] + "]");
        }

        // Ensure we have at least one HandlerMapping, by registering
        // a default HandlerMapping if no other mappings are found.
        if (this.handlerMappings.isEmpty()) {
            initDefaultHandlerMapping();
            logger.info("No HandlerMappings found in servlet '" + getServletName() + "': using default");
        } else {
            // We keep HandlerMappings in sorted order
            Collections.sort(this.handlerMappings, new OrderComparator());
        }
    }
    private void initDefaultHandlerMapping() throws ServletException {
        try {
            HandlerMapping hm = new BeanNameUrlHandlerMapping();
            hm.setApplicationContext(getWebApplicationContext());
            this.handlerMappings.add(hm);
        } catch (ApplicationContextException ex) {
            throw new ServletException("Error initializing default HandlerMapping: " + ex.getMessage(), ex);
        }
    }

12.执行initHandlerAdapters方法,从上下文中获取HandlerAdapter类型的bean,没有则使用默认SimpleControllerHandlerAdapter

 private void initHandlerAdapters() throws ServletException {
        this.handlerAdapters = new ArrayList();

        String[] has = getWebApplicationContext().getBeanDefinitionNames(HandlerAdapter.class);
        for (int i = 0; i < has.length; i++) {
            initHandlerAdapter(has[i]);
            logger.info("Loaded handler adapter [" + has[i] + "]");
        }

        // Ensure we have at least one HandlerAdapter, by registering
        // a default HandlerAdapter if no other adapters are found.
        if (this.handlerAdapters.isEmpty()) {
            initDefaultHandlerAdapter();
            logger.info("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
        } else {
            // We keep HandlerAdapters in sorted order
            Collections.sort(this.handlerAdapters, new OrderComparator());
        }
    }
    private void initDefaultHandlerAdapter() throws ServletException {
        try {
            HandlerAdapter ha = new SimpleControllerHandlerAdapter();
            ha.setApplicationContext(getWebApplicationContext());
            this.handlerAdapters.add(ha);
        } catch (ApplicationContextException ex) {
            throw new ServletException("Error initializing default HandlerAdapter: " + ex.getMessage(), ex);
        }
    }

13.执行initViewResolver方法,从上下文中获取viewResolver bean,没有则使用默认InternalResourceViewResolver

 private void initViewResolver() throws ServletException {
        try {
            this.viewResolver = (ViewResolver) getWebApplicationContext().getBean(VIEW_RESOLVER_BEAN_NAME);
            logger.info("Loaded view resolver [" + viewResolver + "]");
        } catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default
            this.viewResolver = new InternalResourceViewResolver();
            try {
                this.viewResolver.setApplicationContext(getWebApplicationContext());
            } catch (ApplicationContextException ex2) {
                throw new ServletException("Fatal error initializing default ViewResolver");
            }
            logger.info("Unable to locate view resolver with name '" + VIEW_RESOLVER_BEAN_NAME + "': using default [" + this.viewResolver + "]");
        } catch (BeansException ex) {
            // We tried and failed to load the ViewResolver specified by a bean
            throw new ServletException("Fatal error loading view resolver: bean with name '" + VIEW_RESOLVER_BEAN_NAME + "' is required in servlet '" + getServletName() + "': using default", ex);
        }
    }

14.返回到FrameworkServlet类

15.返回到HttpServletBean类

16.Servlet的init方法执行完毕。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值