Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当JVM启动时,如何在Java中运行初始化器方法?_Java_Maven_Jvm - Fatal编程技术网

当JVM启动时,如何在Java中运行初始化器方法?

当JVM启动时,如何在Java中运行初始化器方法?,java,maven,jvm,Java,Maven,Jvm,我正在构建一个包含一些Java、Maven项目的Java库。在任何项目中都没有main方法,因为它是一个库。在web应用程序中,您可以创建一个实现ServletContextListener的类,它将在服务器启动时执行(例如,当Tomcat启动时)。我也想这样做,但是对于库(它不是web应用程序或控制台应用程序,它只是一个可重用的库)。如果有人编写了一个使用我的库的程序,我希望initializer类在JVM启动时执行,以便执行一些我希望它执行的初始化。我怎么能这么做 谢谢我想问题归结为如何在使

我正在构建一个包含一些Java、Maven项目的Java库。在任何项目中都没有main方法,因为它是一个库。在web应用程序中,您可以创建一个实现ServletContextListener的类,它将在服务器启动时执行(例如,当Tomcat启动时)。我也想这样做,但是对于库(它不是web应用程序或控制台应用程序,它只是一个可重用的库)。如果有人编写了一个使用我的库的程序,我希望initializer类在JVM启动时执行,以便执行一些我希望它执行的初始化。我怎么能这么做


谢谢

我想问题归结为如何在使用对象之前初始化它们。这又取决于执行初始化所需的数据。如果您需要:

  • 要执行不依赖于外部信息的初始化工作,则可以在对象创建时(例如,在构造函数中,或者,如果使用EE框架,则在@PostConstruct注释的方法中)或在类加载时运行的静态初始化块中执行
  • 来自用户环境的数据,类中的静态调用可以提供这一点。同样,这可以在对象构造时完成 用户对如何使用库进行了静态选择,考虑使用属性文件(需要记录文件)。同样,对象构造是进行此操作的时机
  • 用户对使用库所做的动态选择,将在运行时与库协作的对象中的某个位置提供
如果您的初始化工作是资源密集型的,并且您希望在用户的应用程序启动时执行,那么我认为实现这一点的最佳方法是记录需求,并要求用户调用执行初始化的特定方法

从库用户的角度来看,我想知道您的库何时进行初始化工作,以及这项工作有多繁重。我不想让一个库决定什么时候它会消耗资源,特别是在启动时,我可能有很多自己的启动代码、框架代码和无数其他初始化位,所有这些都会导致启动延迟


编辑:需要明确的是,所有这些选项都在应用程序级别。JVM本身已经启动并运行。我们讨论的是应用程序代码的初始化,而不是JVM

您希望在使用(Java)库之前,始终首先执行特定的初始化代码

使用
@PostConstruct
的J2EE/Spring选项已经针对所提出的问题进行了说明。使用JavaSE,您可以通过一个单例类来封装Java库,该类是库其余功能的“入口”

singleton类的构造函数可以在将控制权传递回调用方(主web应用程序)之前调用所有必要的初始化代码


应该是开箱即用的。

如果在命令行上添加一个JAR作为
-javaagent:
,则在运行程序的main之前将调用
premain
方法

e、 g


通常,您只需将库添加到任何java项目中,并导入您愿意使用的类即可。如果要执行初始化器类,那么在其他java程序的主方法中调用它。初始化器在JVM启动时运行是绝对必要的,还是必须在使用任何库代码之前运行?如果不使用库将代码添加到主代码中,则无法完成第一步。第二种是常见的,称为,即初始化延迟到需要时。什么样的初始化?根据它是什么,可能只是将
静态
块放入依赖于所述初始化的类中。或者,可能需要通过文档向未来的用户传达,在使用库之前需要进行一些预配置。这实际上取决于我们讨论的是哪种初始化。这听起来像是一个X-Y问题,也是一个库不应该做的事情。@DimitriosEfthymiou然后看看我之前给出的链接,或者在web上搜索延迟初始化。如果您需要在使用配置注册表之前从属性文件对其进行初始化,那么它很可能是在首次访问时自动延迟初始化自身的注册表,例如在
静态
初始化程序块中。因此,本质上,您建议我应该为每个项目创建一个API网关或外观。我想使用初始化代码,这样我就可以在JVM完成启动/初始化之前,在一开始就将prop文件中的属性注册到配置注册表中。因此,问题是当JVM启动时,我如何从prop文件(存在于src/main/resources中)注册prop?您可以向主web应用程序添加@PostConstruct注释方法。该方法可以读取您提到的属性,然后调用LibraryInstance(可能传递相关的参数子集——上面的代码示例中没有显示),以便在JVM启动期间实例化库。静态块是完美的,但不幸的是,当有人第一次使用该类(lazy init)时,而不是当类加载器在JVM启动时,它就会执行。我想使用初始化代码,这样我就可以在JVM完成其启动/初始化之前,即在任何人调用库之前,在一开始就将一些属性从prop文件注册到配置注册表中。所以,问题是当JVM启动时,如何从prop文件(存在于src/main/resources中)注册prop?静态块将初始化
public class LibraryInstance {

    private FunctionalClass1 functionalClass1;
    private FunctionalClass2 functionalClass2;
    ...

    private LibraryInstance() { runInitializingCode(); }
    private static final LibraryInstance instance = new LibraryInstance();
    public static LibraryInstance getInstance() {
        return instance;
    }

    private void runInitializingCode() { 
        ....
    }
}
import java.lang.instrument.Instrumentation;

public class Agent {
  public static void premain(String args, Instrumentation instrumentation){
    // early initalization
  }
}