All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.seven.cow.beans.spring.boot.starter.layered.BusinessControllerInitialize Maven / Gradle / Ivy

There is a newer version: 0.2.4
Show newest version
package com.seven.cow.beans.spring.boot.starter.layered;

import com.seven.cow.spring.boot.autoconfigure.util.LoggerUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.MethodIntrospector;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 初始化业务 @Controller 接口
 */
public class BusinessControllerInitialize implements ApplicationListener {

    private final static Map, Map> MAPPING_LOGGING = new ConcurrentHashMap<>();

    private final static AtomicInteger atomicInteger = new AtomicInteger(0);

    private final static ReentrantLock LOCK = new ReentrantLock();

    @Autowired
    private ApplicationContext context;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
        if (context.equals(applicationContext)) {
            return;
        }
        Map mappingMap = applicationContext.getBeansWithAnnotation(Controller.class);
        RequestMappingHandlerMapping requestMappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
        Method getMappingForMethod = ReflectionUtils.findMethod(RequestMappingHandlerMapping.class, "getMappingForMethod", Method.class, Class.class);
        mappingMap.forEach((key, handler) ->
        {
            assert getMappingForMethod != null;
            getMappingForMethod.setAccessible(true);
            Class handlerType = handler.getClass();
            if (handlerType != null) {
                Class userType = ClassUtils.getUserClass(handlerType);
                Map methods = MethodIntrospector.selectMethods(userType, (MethodIntrospector.MetadataLookup) method ->
                {
                    try {
                        return (RequestMappingInfo) getMappingForMethod.invoke(requestMappingHandlerMapping, method, userType);
                    } catch (Throwable ex) {
                        throw new IllegalStateException("Invalid mapping on handler class [" +
                                userType.getName() + "]: " + method, ex);
                    }
                });
                Map mappingLogging = new HashMap<>(methods.size());
                methods.forEach((method, mapping) ->
                {
                    Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
                    try {
                        LOCK.lock();
                        Set requestMappingInfoSet = new HashSet<>(requestMappingHandlerMapping.getHandlerMethods().keySet());
                        for (RequestMappingInfo requestMappingInfo : requestMappingInfoSet) {
                            if (requestMappingInfo.equals(mapping)) {
                                requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);
                            }
                        }
                        requestMappingHandlerMapping.registerMapping(mapping, handler, invocableMethod);
                        mappingLogging.put(method, mapping.toString());
                    } catch (Exception ex) {
                        LoggerUtils.error(ex.getMessage(), ex);
                    } finally {
                        LOCK.unlock();
                    }
                });
                MAPPING_LOGGING.put(userType, mappingLogging);
            }
        });
        atomicInteger.incrementAndGet();
        synchronized (atomicInteger) {
            atomicInteger.notify();
        }
    }

    public static void loggingMapping(int contentTotal) {
        for (; ; ) {
            synchronized (atomicInteger) {
                if (contentTotal == atomicInteger.get()) {
                    break;
                } else {
                    try {
                        atomicInteger.wait();
                    } catch (InterruptedException e) {
                        LoggerUtils.error(e.getMessage(), e);
                    }
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        MAPPING_LOGGING.forEach((userType, methods) ->
                sb.append(formatMappings(userType, methods)));
        LoggerUtils.info(sb.toString());
    }

    public static String formatMappings(Class userType, Map methods) {
        String formattedType = Arrays.stream(ClassUtils.getPackageName(userType).split("\\."))
                .map(p -> p.substring(0, 1))
                .collect(Collectors.joining(".", "", "." + userType.getSimpleName()));
        Function methodFormatter = method -> Arrays.stream(method.getParameterTypes())
                .map(Class::getSimpleName)
                .collect(Collectors.joining(",", "(", ")"));
        return methods.entrySet().stream()
                .map(e ->
                {
                    Method method = e.getKey();
                    return e.getValue() + ": " + method.getName() + methodFormatter.apply(method);
                })
                .collect(Collectors.joining("\n\t", "\n\t" + formattedType + ":" + "\n\t", ""));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy