栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring mvc源码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring mvc源码

初始化

tomcat会读取web.xml,从里面获取servlet class得到DispatcherServlet,父类是HttpServlet,有doget,dopost,传入request,传出response。
tomcat在开始的时候会调用HttpServlet的init方法,子类重写这个方法。frameworkServlet继承HttpServlet,增加WebApplicationContext。
DispatcherServlet继承frameworkServlet,增加HandlerMapping和handlerAdapters。
最开始首先创建WebApplicationContext。

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {


            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            prepareBeanFactory(beanFactory);


            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            finishBeanFactoryInitialization(beanFactory);
        }
    }

在obtainFreshBeanFactory的loadBeanDefinitions,会调用getDefaultConfigLocation,Namespace就是xml配置的servlet-name,读取的就是dispatcher-servlet.xml。

    protected String getDefaultConfigLocation() {
        if (getNamespace() != null) {
            return DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX;
        }
        else {
            return DEFAULT_CONFIG_LOCATION;
        }
    }

这里对beanfactory进行BeanDefinition注册。

	    else if(namespaceUri.equals("http://www.springframework.org/schema/context")&& ele.getLocalName().equals("component-scan")){
            //找出需要搜索的包,并注册controller
            NamespaceHandler namespaceHandler=this.namespaceHandlers.get(namespaceUri);
            namespaceHandler.parse(ele,this.registry);
        }
        else if(namespaceUri.equals("http://www.springframework.org/schema/mvc") && ele.getLocalName().equals("annotation-driven")){
            BeanDefinition handlerMappingDef = null;
            try {
                handlerMappingDef = new BeanDefinition(HANDLER_MAPPING_BEAN_NAME);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            this.registry.registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef);

            BeanDefinition handlerAdapterDef = null;
            try {
                handlerAdapterDef = new BeanDefinition(HANDLER_ADAPTER_BEAN_NAME);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            this.registry.registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef);

        }
module不能循环依赖,怎么互相使用对方的类呢?

通过反射

NamespaceHandlerSupport

这个类提供了基本的解析功能,由子类实现init方法来注册parser。

context:component-scan

扫描对应的包,读取类信息,注册beandefinition

    public Set doScan(String... basePackages) {
        Set beanDefinitions = new linkedHashSet<>();
        for (String basePackage : basePackages) {
            Set candidates = findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {

                String beanName = null;
                try {
                    beanName = candidate.getBeanClass().getName();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }


                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);

                beanDefinitions.add(definitionHolder);
                this.registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

            }
        }
        return beanDefinitions;
    }
    private Set scanCandidateComponents(String basePackage) throws Exception {
        Set candidates = new linkedHashSet<>();
        try {
            String packageSearchPath = PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    basePackage + '/' + this.resourcePattern;
            Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);

            for (Resource resource : resources) {
                try {
                    metadataReader metadataReader = new SimplemetadataReader(resource);
                    if (isCandidateComponent(metadataReader)) {
                        candidates.add(new BeanDefinition(metadataReader.getClassName()));
                    }

                }
                catch (Throwable ex) {
                    throw new Exception(
                            "Failed to read candidate component class: " + resource, ex);
                }


            }
        }
递归扫描注解

使用深度优先搜索,扫描注解。如果包含@component,则把这个类注册到容器里。

	public void visitEnd() {
        super.visitEnd();

        Class annotationClass = this.annotationType;
        if (annotationClass != null) {
            Set visited = new linkedHashSet<>();
            Annotation[] metaAnnotations = AnnotationUtils.getAnnotations(annotationClass);
            if (!ObjectUtils.isEmpty(metaAnnotations)) {
                for (Annotation metaAnnotation : metaAnnotations) {
                    recursivelyCollectmetaAnnotations(visited, metaAnnotation);
                }
            }
            Set metaAnnotationTypeNames = new linkedHashSet<>(visited.size());
            for (Annotation ann : visited) {
                metaAnnotationTypeNames.add(ann.annotationType().getName());
            }
            this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames);
        }
    }

    private void recursivelyCollectmetaAnnotations(Set visited, Annotation annotation) {
        Class annotationType = annotation.annotationType();
        if (visited.add(annotation)) {
            try {
                for (Annotation metametaAnnotation : annotationType.getAnnotations()) {
                    recursivelyCollectmetaAnnotations(visited, metametaAnnotation);
                }
            }
            catch (Throwable ignored) {

            }
        }
    }
mvc:annotation-driven

注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter到容器里。

RequestMappingHandlerMapping

RequestMappingHandlerMapping实现了InitializingBean接口,在创建bean的initialize时候,beanfactory会调用这个方法。

    public void afterPropertiesSet() {
        initHandlerMethods();
    }

    protected abstract boolean isHandler(Class beanType);


    protected void initHandlerMethods() {
        String[] beanNames = obtainApplicationContext().getBeanNamesForType(Object.class);
        for (String beanName : beanNames) {
            
                Class beanType = null;
                try {
                    beanType = obtainApplicationContext().getType(beanName);
                }
                catch (Throwable ignored) {
                    
                }
                if (beanType != null && isHandler(beanType)) {
                    detectHandlerMethods(beanName);
                }
            
        }
    }

检查beanfactory里的所有bean,看看有没有注解。

    protected boolean isHandler(Class beanType) {
        return beanType.isAnnotationPresent(Controller.class) || beanType.isAnnotationPresent(RequestMapping.class);
    }

检查所有方法,看看有没有RequestMapping,有的话记录下path、方法、bean。

    protected void detectHandlerMethods(final Object handler) {
        Class handlerType = (handler instanceof String ?
                obtainApplicationContext().getType((String) handler) : handler.getClass());

        if (handlerType != null) {
            final Class userType = handlerType;
            Map methods = MethodIntrospector.selectMethods(userType,
                    method -> {
                        try {
                            return getMappingForMethod(method, userType);
                        }
                        catch (Throwable ex) {
                            throw new IllegalStateException("Invalid mapping on handler class [" +
                                    userType.getName() + "]: " + method, ex);
                        }
                    });
          
            for (Map.Entry entry : methods.entrySet()) {
                Method invocableMethod = entry.getKey();
                T mapping = entry.getValue();
                registerHandlerMethod(obtainApplicationContext().getBean((String) handler), invocableMethod, mapping);
            }
        }
    }
```java
    private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
        RequestMapping requestMapping = element.getAnnotation(RequestMapping.class);
        if(requestMapping==null){
            return null;
        }
        return createRequestMappingInfo(requestMapping);
    }

    protected RequestMappingInfo createRequestMappingInfo(
            RequestMapping requestMapping) {

        return new RequestMappingInfo(requestMapping.path());

    }
    protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) {
        RequestMappingInfo info = createRequestMappingInfo(method);
        if (info != null) {
            RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
            if (typeInfo != null) {
                info = typeInfo.combine(info);
            }
        }
        return info;
    }
```java
    public RequestMappingInfo combine(RequestMappingInfo other) {
        String paths = this.path+other.path;
        return new RequestMappingInfo(paths);
    }
RequestMappingHandlerAdapter

负责解析参数,把结果转换成json,初始化的时候注册这个adapter到容器里。

处理请求

初始化负责把对应的handler注册到容器里,构建路由等。那么怎么处理请求的呢?其实就是根据request的uri进行路由,调用相应的方法,在把结果写进response。
主要是就是获取注解的参数,然后根据参数获取request里相应的参数。调用函数后,再写入json。

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception{
        HttpServletRequest processedRequest = request;

        HandlerExecutionChain mappedHandler = null;
        mappedHandler = getHandler(processedRequest);
        if (mappedHandler == null) {
            noHandlerFound(processedRequest, response);
            return;
        }
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        ha.handle(processedRequest, response, mappedHandler.getHandler());

    }
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
        String lookupPath = request.getServletPath();
        T mapping = this.mappingRegistry.getMappingsByUrl(lookupPath);

        HandlerMethod handlerMethod = this.mappingRegistry.getMappings().get(mapping);
        
        return handlerMethod;

    }
    protected void  invokeHandlerMethod(HttpServletRequest request,
                                               HttpServletResponse response, HandlerMethod handlerMethod) throws Exception{
        Object []args=getMethodArgumentValues(request,handlerMethod);

        Object returnValue = handlerMethod.getMethod().invoke(handlerMethod.getBean(),args);
        this.requestResponseBodyMethodProcessor.handleReturnValue(returnValue,response);

    }
    public void handleReturnValue(Object returnValue, HttpServletResponse response){
        try {
            response.setHeader("Content-Type", "application/json");
            this.gson.toJson(returnValue, response.getWriter());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/439418.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号