简体   繁体   English

如何从外部目录中的 jar 创建 bean

[英]How to create a bean from a jar in external directory

I have a basic spring application that simply loads a bean and thats it.我有一个基本的 spring 应用程序,它只需加载一个 bean 就可以了。 I know that within the project I can use the annotation @Component within a class to mark it as a bean and the spring application will find it and act accordingly.我知道在项目中,我可以使用 class 中的注释 @Component 将其标记为 bean,spring 应用程序将找到它并采取相应措施。

However, I am currently trying to place the component in a jar ie plugin.jar in the external directory /Users/me/plugin.jar.但是,我目前正在尝试将组件放在外部目录 /Users/me/plugin.jar 中的 jar 即 plugin.jar 中。 I am at a lost for how to get spring to search within that jar for an annotated class instead of the local package. I am at a lost for how to get spring to search within that jar for an annotated class instead of the local package. Is this even possible?这甚至可能吗?

I want to be able to load the bean from the jar without the jar being included in the class-path but rather by searching the directory for the jar and dynamically creating the bean based on whatever Jar is in there. I want to be able to load the bean from the jar without the jar being included in the class-path but rather by searching the directory for the jar and dynamically creating the bean based on whatever Jar is in there.

I have used Java reflection and a URLClassLoader for dynamically loading classes from the jar but cannot figure out how to do the same thing in Spring.我已经使用 Java 反射和 URLClassLoader 从 jar 动态加载类,但无法弄清楚如何在 Spring 中做同样的事情。 Any help or direction on how to get started is greatly appreciated.非常感谢任何有关如何开始的帮助或指导。 Thanks!谢谢!

Additional Info: The spring application is meant to be designed so that while it is running, it scans a designated directory for any jars, if it finds a jar it creates a bean from one of classes inside.附加信息:spring 应用程序的设计目的是,当它运行时,它会扫描指定目录中的任何 jars,如果它找到一个 jar,它会从其中创建一个类。 I cannot find out how to get the spring application to search scan a specified directory for jars to use as components.我无法找到如何让 spring 应用程序搜索扫描指定目录以将 jars 用作组件。 Everything I find simply references classes within the project.我发现的所有内容都只是引用项目中的类。

You can create a Configuration where you initiate the required bean from external jar.您可以创建一个配置,从外部 jar 启动所需的 bean。

 @Configuration
    public class AppConfig {

        @Bean
        public MyBean myBean() {
            return new YourExternalClassName();
        }

    }

Use the @ComponentScan annotation on a configuration class, and specify your external component's package:在配置 class 上使用@ComponentScan注释,并指定外部组件的 package:

@Configuration
@ComponentScan(basePackages={"com.foo.bar"})
public class Config { }

You can also define a meta annotion in your external jar:您还可以在外部 jar 中定义元注释:

@Retention(value=RUNTIME)
@Target(value=TYPE)
@ComponentScan(basePackages={"com.foo.bar"})
public @interface EnableExternalFoo { }

And apply this to a configuration class:并将其应用于配置 class:

@Configuration
@EnableExternalFoo
public class Config { }

If your plugin.jar is a Spring project with @Component, you can just scan the package:如果您的 plugin.jar 是带有 @Component 的 Spring 项目,您只需扫描 package:

@ComponentScan(basePackages = {"com.exp"}, basePackageClasses = DependencyBasePackageClass.class)

//external.jar
package com.exp;

import org.springframework.stereotype.Component;

@Component
public class ExpBean {
}

If the bean is just a class in the external.jar, you can create Factory or Singleton it and use it as a Bean.如果 bean 只是 external.jar 中的 class,则可以创建 Factory 或 Singleton 并将其用作 Bean。

However, I am currently trying to place the component in a jar ie plugin.jar in the external directory /Users/me/plugin.jar.但是,我目前正在尝试将组件放在外部目录 /Users/me/plugin.jar 中的 jar 即 plugin.jar 中。 I am at a lost for how to get spring to search within that jar for an annotated class instead of the local package. I am at a lost for how to get spring to search within that jar for an annotated class instead of the local package. Is this even possible?这甚至可能吗?

You could add the JAR in the classpath of the application at runtime.您可以在运行时将 JAR 添加到应用程序的类路径中。 But the problem is that at compile time you also need to have the jar as a compilation dependency.但问题是在编译时您还需要将 jar 作为编译依赖项。
Since you use Spring Boot, it means that you use Maven or Gradle as build tool.由于您使用 Spring Boot,这意味着您使用 Maven 或 Gradle 作为构建工具。
In that case, you don't have to use local directories to specify your external jars otherwise your builds will be reproducible only on your machine and in a very specific state of your machine (the jar has to be in the specified directory).在这种情况下,您不必使用本地目录来指定您的外部 jars,否则您的构建将只能在您的机器上和您机器的非常特定的 state 中重现(Z68995FCBF432492D1548ZD94DAC04 在指定的目录中)。 You don't want to defeat the build tool advantages.您不想破坏构建工具的优势。
A more robust way would be to apply the maven/gradle way:更强大的方法是应用 maven/gradle 方式:
- define that jar as a maven/gradle artifact - 将 jar 定义为 maven/gradle 工件
- push it to your repo (local and central if you use that) - 将其推送到您的存储库(如果您使用它,则为本地和中央)
- declare the jar in the dependencies of the pom.xml / build.gradle of your application - 在应用程序的pom.xml / build.gradle的依赖项中声明 jar

Then in your application you can declare a bean of the Foo class defining in the JAR such as:然后在您的应用程序中,您可以声明在 JAR 中定义的Foo class 的 bean,例如:

@Configuration
public class ExternalBeanConfig {

        @Bean
        public Foo foo() {
            return new Foo();
        }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM