一個java實現代碼(服務)編排的思路(未完)


創建模板java文件

使用freemaker創建一個java代碼運行的模板,整體設計類似於模板方法設計模式,在模板內規定了程序運行的主體步驟,細節實現放在模板中的key中

前端配置模塊

每個模塊的背后都是一段提前寫好的代碼,這段代碼是可以嵌入到之前准備好的模板的

用戶通過拖拽模塊來實現自己的邏輯

用戶拖拽好模塊並保存,后端基於模板及用戶的配置信息,生成java文件

編譯java文件

編輯java文件,加載相關的類,加入到spring容器中

后端提前准備好一個通用接口

這個接口的核心邏輯就是根據不同的java類名來調用spring容器中的類來完成邏輯。

已經寫的demo類

@RestController
public class TestController {


    @Autowired
    private UserService userService;

    @GetMapping("/test")
    public String test01() throws Exception {
        String hello = userService.sayHello("hello");
        return hello;
    }
}
@Service
public class UserService {

    public String sayHello(String name) throws Exception {
        ReflectObj reflectObj = LoadClassUtil.map.get(name);
        return reflectObj.invoke();
    }
}
public class LoadClassUtil {


    public static Map<String, ReflectObj> map = new HashMap<>();
    static {
        try {
            loadClass("com.example.javasou.Hello");
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    //加載class對象
    public static void loadClass(String className) throws Exception {
        javac("E:\\learn\\java\\Hello.java");
        Thread.sleep(2000);
        MyClassLoader myClassLoader = new MyClassLoader();
        myClassLoader.setClassPath("E:\\learn\\java\\Hello.class");
        Class clazz = myClassLoader.loadClass(className);
        DynamicLoadUtils.addBean(clazz,"hello111",SpringContextUtil.getApplicationContext());
        Object obj = clazz.newInstance();
        map.put("hello",new ReflectObj(clazz, obj));
    }

    public static void javac(String packageAndClass) throws IOException {
        Runtime.getRuntime().exec("javac  " + packageAndClass);
    }
}
public class MyClassLoader extends ClassLoader {
    //需要加載類的路徑
    private String classPath;

    public MyClassLoader() {
    }

    public MyClassLoader(String classPath) {
        super();
        this.classPath = classPath;
    }
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> clazz = null;
        // 獲取class文件字節碼數組
        byte[] clazzByteArr = getData();

        if (clazzByteArr != null) {
            // 將class的字節碼數組轉換成class類的實例
            clazz = defineClass(name, clazzByteArr, 0, clazzByteArr.length);
        }
        return clazz;
    }

    private byte[] getData() {
        File file = new File(this.classPath);
        if (file.exists()) {
            FileInputStream in = null;
            ByteArrayOutputStream out = null;
            try {
                in = new FileInputStream(file);
                out = new ByteArrayOutputStream();

                byte[] buffer = new byte[1024];
                int size = 0;
                while ((size = in.read(buffer)) != -1) {
                    out.write(buffer, 0, size);
                }

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return out.toByteArray();
        } else {
            return null;
        }
    }
    public String getClassPath() {
        return classPath;
    }
    public void setClassPath(String classPath) {
        this.classPath = classPath;
    }
}
public class ReflectObj {

    public ReflectObj(Class aClass, Object object) {
        this.aClass = aClass;
        this.object = object;
    }

    private Class aClass;
    private Object object;

    public String invoke() throws Exception {
        Method method = aClass.getMethod("sayHello", String.class);
        return (String) method.invoke(object, "123");
    }
}
@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    //獲取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通過name獲取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    //通過class獲取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    //通過name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}
public class DynamicLoadUtils {
    
    public static void registerController(String controllerBeanName) throws Exception {
        final RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping)
                SpringContextUtil.getBean("requestMappingHandlerMapping");

        if (requestMappingHandlerMapping != null) {
            String handler = controllerBeanName;
            Object controller = SpringContextUtil.getBean(handler);
            if (controller == null) {
                return;
            }
            unregisterController(controllerBeanName);
            //注冊Controller
            Method method = requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().
                    getDeclaredMethod("detectHandlerMethods", Object.class);
            method.setAccessible(true);
            method.invoke(requestMappingHandlerMapping, handler);
        }
    }

    public static void unregisterController(String controllerBeanName) {
        final RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping)
                SpringContextUtil.getBean("requestMappingHandlerMapping");
        if (requestMappingHandlerMapping != null) {
            String handler = controllerBeanName;
            Object controller = SpringContextUtil.getBean(handler);
            if (controller == null) {
                return;
            }
            final Class<?> targetClass = controller.getClass();
            ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
                @Override
                public void doWith(Method method) {
                    Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
                    try {
                        Method createMappingMethod = RequestMappingHandlerMapping.class.
                                getDeclaredMethod("getMappingForMethod", Method.class, Class.class);
                        createMappingMethod.setAccessible(true);
                        RequestMappingInfo requestMappingInfo = (RequestMappingInfo)
                                createMappingMethod.invoke(requestMappingHandlerMapping, specificMethod, targetClass);
                        if (requestMappingInfo != null) {
                            requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, ReflectionUtils.USER_DECLARED_METHODS);
        }
    }

    public static void addBean(String className, String serviceName, ApplicationContext app) {
        try {
            Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
            registerBean(serviceName, beanDefinitionBuilder.getRawBeanDefinition(), app);
        } catch (ClassNotFoundException e) {
            System.out.println(className + ",主動注冊失敗.");
        }
    }

    public static void addBean(Class clazz, String serviceName, ApplicationContext app) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        registerBean(serviceName, beanDefinitionBuilder.getRawBeanDefinition(), app);
    }

    private static void registerBean(String beanName, BeanDefinition beanDefinition, ApplicationContext context) {
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) context;
        BeanDefinitionRegistry beanDefinitonRegistry = (BeanDefinitionRegistry) configurableApplicationContext
                .getBeanFactory();
        beanDefinitonRegistry.registerBeanDefinition(beanName, beanDefinition);
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM