有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在普通Java中使用PostConstruct

我正在开发纯java代码(没有bean或容器框架),我希望实现@PostConstruct/@PreDestroy功能。可能吗

我编写了一个示例代码来检查可行性(下面的示例代码)。但是没有调用PostContract()和beforeDestroy()方法

如何实现这一点

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class Test {

    public static void main (String...strings) {
        Test test = new Test();
        System.out.println("Ready....");
        test.sayHello();
        System.out.println("Done...");

    }

    private void sayHello () {
        System.out.println("Hello World !! ");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("PostConstruct is called .. ");
    }

    @PreDestroy
    public void beforeDestroy () {
        System.out.println("beforeDestroy is called ");
    }

}

输出是

Ready....
Hello World !! 
Done...

共 (3) 个答案

  1. # 1 楼答案

    理论上,您可以有一个静态工厂方法,它在构建对象之后调用init方法

    private final init(){
         .. your stuff after the constructor
    }
    
    public static MyObject of(int x){
        MyObject obj = new MyObject(x);
        init();
        return obj;
    }
    

    您可以在构造函数中执行同样的操作,但我不喜欢在构造函数中调用方法。在这种情况下,该方法必须是final,以便不会被重写

  2. # 2 楼答案

    最简单的方法是实现您自己的注释和一个实用程序类来管理实例,然后您可以在实例化类之后为post构造执行方法,并在销毁引用之前预销毁

    在构造函数中最后调用一个方法实际上是一样的,我不认为在任何情况下它都是不同的

    如果您知道自己在做什么,那么调用finalize也是一个不错的选择,因为它不能根据jvm和系统配置进行调用,但实际上它不是预析构函数,而是析构函数本身,因为您不能抛出异常

    您可以实现AutoCloseable接口,并在try with resources中实例化该类,并实现将要调用的close方法

  3. # 3 楼答案

    在您的问题上提到的注释已经说明了这一点:如果您不使用框架或工具来处理注释,那么就不可能调用这些@PostConstruct@PreDestroy方法。附带说明:您也可以编写自己的AnnotationProcessor,但最终可能会编写一个框架,您可以使用自己选择的CDI容器(例如Weld、OpenWebBeans等)

    现在,如果没有注释,您如何解决它?这取决于你想要实现什么

    例如,如果在构建对象之后没有调用@PostConstruct并不重要,那么实例初始化块可能会满足您的需要,例如

    class Some {
    
      {
        // your initialization code... however! this is not the same as @PostConstruct 
      }
    }
    

    关于@PreDestroy,您可以覆盖^{}

    在提供自己的finalize-implementation时要小心,并在提供之前阅读一些关于它的文章

    然而,这两种解决方案都不是注释的1:1替代品,但它们可能正是您所寻找的

    下面是一个示例类:

    class PreDestroyPostConstruct {
    
      PreDestroyPostConstruct() {
        System.out.println("constructor");
      }
    
      {
        System.out.println("initialization block");
      }
    
      @Override
      protected void finalize() throws Throwable {
        System.out.println("finalize");
      }
    }
    

    演示输出:

    PreDestroyPostConstruct obj = new PreDestroyPostConstruct();
    obj = null;
    System.out.println("Program finishing");
    

    可能的产出:

    initialization block
    constructor
    finalize
    Program finishing
    

    注意,不能保证在"Program finishing"部分之前调用finalize,甚至可能在VM关闭之前没有调用/完成它