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

时间:2018-04-27 20:50:27

标签: java maven jvm

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

谢谢

3 个答案:

答案 0 :(得分:1)

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

  • 执行不依赖于外部信息的初始化工作,然后您可以在对象创建时执行此操作(例如,在构造函数中,或者,如果您使用EE框架,则使用类似@PostConstruct注释的方法),或者在静态初始化块中,将在类加载时运行。
  • 来自用户环境的数据,System类中的静态调用可以提供此功能。同样,这可以在对象构建时完成。
  • 用户对如何使用库的静态选择,考虑使用属性文件(需要记录)。同样,对象构造是时候做到这一点。
  • 用户对使用您的库所做的动态选择,这将在运行时在与您的库协作的对象中的某个位置提供。

如果您的初始化工作是资源密集型的,并且您希望在用户的应用程序启动时执行此操作,那么我认为实现此目的的最佳方法是记录需求并要求用户调用将执行初始化的特定方法。

从图书馆用户的角度来看,我想知道您的图书馆何时进行初始化工作以及该工作的重要程度。我不希望图书馆决定何时会消耗资源,特别是在启动时我可能有很多自己的启动代码,框架代码和无数其他初始化位都会导致启动延迟。

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

答案 1 :(得分:1)

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

使用@PostConstruct的J2EE / Spring选项已针对提出的问题进行了解决。使用Java SE,您可以通过 singleton 类封装Java库 - 这是一个类,它是库的其余功能的“入口”。

在将控制权传递给调用者(主要的web应用程序)之前,单例类的构造函数可以调用所有必需的初始化代码。

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() { 
        ....
    }
}

应该开箱即用。

答案 2 :(得分:1)

如果在命令行中将JAR添加为-javaagent:,则在正在运行的程序的主体之前,将调用{em> 方法。

e.g。

premain

https://zeroturnaround.com/rebellabs/how-to-inspect-classes-in-your-jvm/