Spring Boot加载外部Jar包

本文介绍了如何在Spring Boot中加载外部Jar包,并将其类注册为Spring Bean。主要步骤包括构建自定义ClassLoader、使用@Import注解扫描、定义Scanner方法、覆写PathMatchingResourcePatternResolver以及将导入类引入Spring上下文。

Spring Boot加载外部Jar包

项目有一个需求,需要通过spring加载配置下的Jar包,将Jar包中的类注册成Spring的一个Bean以供后续使用。

1、构建自己的ClassLoader。

关于java自己的ClassLoader的加载方式,详情可移步此篇博客

以下是我定义的JarClassLoader,将Jar包转换为URL,通过URLClassLoader去加载。



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.talend.dataprep.api.action.Action;
import org.talend.dataprep.api.action.ActionDefinition;

import java.io.*;
import java.lang.reflect.Modifier;
import java.net.*;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @Author: chang sir
 * @Date: 2021/3/11 0011上午 10:36
 * @Email: 
 */
public class JarUrlClassLoader extends URLClassLoader {


    /** logger */
//    private static final Logger LOGGER = LoggerFactory.getLogger(JarUrlClassLoader.class);

    public JarUrlClassLoader(){
        super(new URL[]{});
    }
    public JarUrlClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    @Override
    protected void addURL(URL url) {
        super.addURL(url);
    }

}

2、构建Import通过Import注解扫描加入。

定义一个Import类,覆写ImportBeanDefinitionRegistrar接口,



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.talend.dataprep.JarUrlClassLoader;
import org.talend.dataprep.api.action.Action;
import org.talend.dataprep.api.action.ActionDefinition;
import org.talend.dataprep.exception.TDPException;
import org.talend.dataprep.exception.error.CommonErrorCodes;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: chang sir
 * @Date: 2021/3/11 0011下午 19:24
 * @Email: 
 */
public class PlugActionImport implements ImportBeanDefinitionRegistrar {

    /** logger */
    private static final Logger LOGGER = LoggerFactory.getLogger(PlugActionImport.class);
    public static final String PREFIX = "action#";
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {

        GenericApplicationContext context = new GenericApplicationContext();
        String jarPath = jarPath();
        JarUrlClassLoader loader = getLoader();
        if(StringUtils.isEmpty(jarPath)){
            LOGGER.info("please config a absolute path for action plug jar. ex: /data/java/*
Spring Boot导入外部jar有多种方法,下面为你详细介绍: ### 使用Maven添加依赖 如果使用Maven添加依赖,可直接使用依赖中的类或方法。在`pom.xml`文件里添加依赖,当该依赖存在于Maven仓库时,Maven会自动下载并添加到项目的类路径中。具体示例如下: ```xml <dependency> <groupId>your.groupId</groupId> <artifactId>your-artifactId</artifactId> <version>your-version</version> </dependency> ``` ### 使用system scope声明依赖 当依赖来自外部jar,而非Maven仓库时,可使用`system scope`来声明依赖。需要在代码中手动导入外部JAR中的类,在`pom.xml`文件中添加如下配置: ```xml <dependency> <groupId>your.groupId</groupId> <artifactId>your-artifactId</artifactId> <version>your-version</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resource/lib/your-jar-file.jar</systemPath> </dependency> ``` 其中,`<systemPath>`中的`${project.basedir}`是项目基本路径,需把jar所在的路径添加在后面,即`/src/main/resource/lib/jar文件名` [^3]。 ### 采用直接放在pom文件同级目录下的方式 可以将外部jar直接放在`pom`文件同级目录下,同时在`pom`文件添加依赖。示例配置如下: ```xml <dependency> <groupId>your.groupId</groupId> <artifactId>your-artifactId</artifactId> <version>your-version</version> <scope>system</scope> <systemPath>${pom.basedir}/libs/your-jar-file.jar</systemPath> </dependency> ``` ### 自定义类加载加载 可以自定义类加载器来加载外部jar。以下是一个自定义`JarUrlClassLoader`的示例: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.talend.dataprep.api.action.Action; import org.talend.dataprep.api.action.ActionDefinition; import java.io.*; import java.lang.reflect.Modifier; import java.net.*; import java.util.Enumeration; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class JarUrlClassLoader extends URLClassLoader { // private static final Logger LOGGER = LoggerFactory.getLogger(JarUrlClassLoader.class); public JarUrlClassLoader(){ super(new URL[]{}); } public JarUrlClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } @Override protected void addURL(URL url) { super.addURL(url); } } ``` 通过这个自定义的类加载器,可将Jar转换为URL,再通过`URLClassLoader`去加载 [^2]。 ### 构建Import通过Import注解扫描加入 可以构建Import,通过`Import`注解扫描加入外部jar中的类 [^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值