当前位置: 首页>后端>正文

springboot+mybatis-plus加载第三方jar包并注册为bean供系统调用

环境
springboot2.6.6,mybatis-plus3.5.1

    @Autowired
    SqlSessionFactory factory;

    @Autowired
    SpringContextUtils springContextUtils;

    ConfigurableApplicationContext application = (ConfigurableApplicationContext) SpringContextUtils.getApplicationContext();
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)application.getBeanFactory();
        ClassLoader beanClassLoader = beanFactory.getBeanClassLoader();
        List<Class<?>> list = RegisterApplication.loadClass("D:\111\2", beanClassLoader);
        List<Resource> resourceList = RegisterApplication.loadResource("D:\111\2", beanClassLoader);
        Configuration targetConfiguration = factory.getConfiguration();
        //先加载jar包里的xml文件,这一步必须在前面
        for (Resource mapperLocation : resourceList) {
            if (mapperLocation == null) {
                continue;
            }
            try {
                XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
                        targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
                xmlMapperBuilder.parse();
            } catch (Exception e) {
                throw new JeecgBootException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
            } finally {
                ErrorContext.instance().reset();
            }
        }

        for(Class<?> clazz : list){
            if(!clazz.isInterface()){
                Component c = clazz.getAnnotation(Component.class);
                String beanName = null;
                if(c != null){
                    beanName = c.value();
                }else{
                    Service s = clazz.getAnnotation(Service.class);
                    if(s != null){
                        beanName = s.value();
                    }
                }
                if(beanName != null){
                    //注册bean
                    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
                    if(!beanFactory.isBeanNameInUse(beanName)){
                        beanFactory.registerBeanDefinition(beanName,builder.getRawBeanDefinition());
                    }
                }
            }else{
                Mapper r = clazz.getAnnotation(Mapper.class);
                if(r != null){
                    //加载mybatisPlus缓存,这一步必须在加载xml之后
                    String resource = clazz.getName().replace(StringPool.DOT, StringPool.SLASH) + ".java (best guess)";
                    MapperBuilderAssistant assistant = new MapperBuilderAssistant(targetConfiguration, resource);
                    GlobalConfigUtils.getSqlInjector(targetConfiguration).inspectInject(assistant, clazz);

                }
            }
        }
        //扫描mapper,并注册成bean
        try{
            Object obj = SpringContextUtils.getBean(MapperScannerConfigurer.class);
            MapperScannerConfigurer mapperScanner = (MapperScannerConfigurer) obj;
            mapperScanner.setProcessPropertyPlaceHolders(false);
            mapperScanner.setBasePackage("com.antjet.**.mapper*");
            mapperScanner.postProcessBeanDefinitionRegistry(beanFactory);
            mapperScanner.setProcessPropertyPlaceHolders(true);
        }catch (NoSuchBeanDefinitionException e){
            log.error("未获取到MapperScannerConfigurer");
        }
        AbstractNodeEvent fybzdEvent = (AbstractNodeEvent)SpringContextUtils.getBean("fybzdEvent");
        System.out.println(fybzdEvent.verifyPass("f55b1682f833449393c07b4f2589653f"));

下面是工具类

package org.jeecg.modules.util;


import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


public class RegisterApplication {
    /**
     * 从本地磁盘的某个路径上加载类, 如果是class文件:
     * filePath路径应该为class文件包名的上一级,如D:\workspace\classes\com\test\helloworld.class,那么filePath则应该是D:\workspace\classes
     * 如果是jar包:
     * 则是jar包所在目录,如D:\workspace\classes\helloword.jar,那么filePath则应该为D:\workspace\classes
     *
     */
    public static List<Class<?>> loadClass(String filePath, ClassLoader beanClassLoader) {
        List<Class<?>> classList = new ArrayList<>();
        File file = new File(filePath);
        if (file.exists() && file.isDirectory()) {
            Stack<File> stack = new Stack<>();
            stack.push(file);
            while (!stack.isEmpty()) {
                File path = stack.pop();
                // 只需要jar包
                File[] classFiles = path.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        return pathname.isDirectory() || pathname.getName().endsWith(".jar");
                    }
                });
                for (File subFile : classFiles) {
                    if (subFile.isDirectory()) {
                        // 如果是目录,则加入栈中
                        stack.push(subFile);
                    } else {
                        URL url = null;
                        JarFile jar = null;
                        Method method = null;
                        Boolean accessible = null;
                        String className = subFile.getAbsolutePath();
                        try {
                            // 反射并调用URLClassLoader的addURL方法
                            URLClassLoader classLoader = (URLClassLoader) beanClassLoader;
                            method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
                            accessible = method.isAccessible();
                            if (accessible == false) {
                                method.setAccessible(true);
                            }
                            //加载jar包
                            url = subFile.toURI().toURL();
                            method.invoke(classLoader, url);
                            // 获取jar
                            jar = new JarFile(new File(className));
                            // 从此jar包 得到一个枚举类
                            Enumeration<JarEntry> entries = jar.entries();
                            // 同样的进行循环迭代
                            while (entries.hasMoreElements()) {
                                // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
                                JarEntry entry = entries.nextElement();
                                String name = entry.getName();
                                // 如果是以/开头的
                                if (name.charAt(0) == '/') {
                                    // 获取后面的字符串
                                    name = name.substring(1);
                                }
                                name = name.replace(File.separatorChar, '.');
                                // 获取class文件
                                if (name.endsWith(".class") && !entry.isDirectory()) {
                                    String className1 = name.substring(0, name.length() - 6);
                                    // 添加到classes
                                    className1 = className1.replace("/", ".");
                                    classList.add(classLoader.loadClass(className1));
                                }
                            }
                        } catch (Exception e) {
                            throw new RuntimeException(e.getMessage());
                        } finally {
                            if (null != jar) {
                                try {
                                    jar.close();
                                } catch (IOException e) {
                                    throw new RuntimeException(e.getMessage());
                                }
                            }
                            if (null != method && null != accessible) {
                                method.setAccessible(accessible);
                            }
                        }

                    }
                }
            }
        }
        return classList;
    }
    public static List<Resource> loadResource(String filePath, ClassLoader beanClassLoader) {
        List<Resource> classList = new ArrayList<>();
        File file = new File(filePath);
        if (file.exists() && file.isDirectory()) {
            Stack<File> stack = new Stack<>();
            stack.push(file);
            while (!stack.isEmpty()) {
                File path = stack.pop();
                // 只需要class文件或者jar包
                File[] classFiles = path.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        return pathname.isDirectory() || pathname.getName().endsWith(".jar");
                    }
                });
                for (File subFile : classFiles) {
                    if (subFile.isDirectory()) {
                        // 如果是目录,则加入栈中
                        stack.push(subFile);
                    } else {
                        URL url = null;
                        JarFile jar = null;
                        Method method = null;
                        Boolean accessible = null;
                        String className = subFile.getAbsolutePath();
                        try {
                            // 反射并调用URLClassLoader的addURL方法
                            URLClassLoader classLoader = (URLClassLoader) beanClassLoader;
                            method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
                            accessible = method.isAccessible();
                            if (accessible == false) {
                                method.setAccessible(true);
                            }
                            // 如果是jar包,加载该jar包
                            url = subFile.toURI().toURL();
                            method.invoke(classLoader, url);
                            // 获取jar
                            jar = new JarFile(new File(className));
                            // 从此jar包 得到一个枚举类
                            Enumeration<JarEntry> entries = jar.entries();
                            // 同样的进行循环迭代

                            while (entries.hasMoreElements()) {
                                // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
                                JarEntry entry = entries.nextElement();
                                String name = entry.getName();
                                // 如果是以/开头的
                                if (name.charAt(0) == '/') {
                                    // 获取后面的字符串
                                    name = name.substring(1);
                                }
                                // 获取class文件
                                if (name.endsWith("Mapper.xml")) {
                                    URL uurl = classLoader.findResource(name);
                                    UrlResource resource = new UrlResource(uurl);
                                    classList.add(resource);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            if (null != jar) {
                                try {
                                    jar.close();
                                } catch (IOException e) {
                                    throw new RuntimeException(e.getMessage());
                                }
                            }
                            if (null != method && null != accessible) {
                                method.setAccessible(accessible);
                            }
                        }

                    }
                }
            }
        }
        return classList;
    }
    public static boolean isBean(Class<?> clazz){
        Object ann = clazz.getAnnotation(Component.class);
        if(ann != null){
            return true;
        }else{
            ann = clazz.getAnnotation(Service.class);
            if(ann != null){
                return true;
            }
        }
        return false;
    }

    public static ClassLoader getClassLoader(String url) {
        try {
            Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
            if (!method.isAccessible()) {
                method.setAccessible(true);
            }
            URLClassLoader classLoader = new URLClassLoader(new URL[]{}, ClassLoader.getSystemClassLoader());
            method.invoke(classLoader, new URL(url));
            return classLoader;
        } catch (Exception e) {
            return null;
        }
    }

}

···

https://www.xamrdz.com/backend/3fq1944157.html

相关文章: