動態創建SpringMVC mapping

 通過源碼發現spring mvc mappinghandler的執行過程,方向推到。需要注意,在registrymapping過後並不能直接調用改url。需要反射獲取父類調用detectHandlerMethods,刷新springmvc映射。

package org.shoper.spring.map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.condition.*;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.annotation.PostConstruct;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Component

public class SpringMapping {
    @PostConstruct
    public void add() throws Exception {
        registory();

    }

    @Autowired
    RequestMappingHandlerMapping requestMappingHanderMapping;
    @Autowired
    AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor;
    @Autowired
    ConfigurableListableBeanFactory factory;

    public void registory() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        A test = new A();
        PatternsRequestCondition patternsRequestCondition = new PatternsRequestCondition("/test");
        RequestMethodsRequestCondition requestMethodsRequestCondition = new RequestMethodsRequestCondition();
        ParamsRequestCondition paramsRequestCondition = new ParamsRequestCondition();
        HeadersRequestCondition headersRequestCondition = new HeadersRequestCondition();
        ConsumesRequestCondition consumesRequestCondition = new ConsumesRequestCondition();
        ProducesRequestCondition producesRequestCondition = new ProducesRequestCondition();
        MediaTypeExpression mediaTypeExpression = new MediaTypeExpression() {
            @Override
            public MediaType getMediaType() {
                return MediaType.APPLICATION_JSON_UTF8;
            }

            @Override
            public boolean isNegated() {
                return false;
            }
        };
        producesRequestCondition.getExpressions().add(mediaTypeExpression);
        RequestMappingInfo requestMappingInfo = new RequestMappingInfo("test", patternsRequestCondition, requestMethodsRequestCondition, paramsRequestCondition, headersRequestCondition, consumesRequestCondition, producesRequestCondition, null);
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) factory;
        autowiredAnnotationBeanPostProcessor.processInjection(test);
//        ((DefaultListableBeanFactory) factory).registerBeanDefinition("test", test);

        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(A.class);
        defaultListableBeanFactory.registerBeanDefinition(A.class.getName(), beanDefinitionBuilder.getBeanDefinition());
//        Test jobCaller = factory.getBean("test", Test.class);
//        defaultListableBeanFactory.destroySingleton("test");

        Class<? extends RequestMappingHandlerMapping> aClass = requestMappingHanderMapping.getClass();
        Class<?> superclass = aClass.getSuperclass().getSuperclass();
        Method detectHandlerMethods = superclass.getDeclaredMethod("detectHandlerMethods", Object.class);
        detectHandlerMethods.setAccessible(true);
        detectHandlerMethods.invoke(requestMappingHanderMapping, A.class.getName());
        requestMappingHanderMapping.registerMapping(requestMappingInfo, test, test.getClass().getMethod("a"));
    }
}
package org.shoper.spring.map;
import org.springframework.web.bind.annotation.ResponseBody;
public class A {
    @ResponseBody
    public String a() {
        System.out.println("asd");
        return "asd";
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章