在@PostConstruct 之后初始化子类

Initialize subclasses after @PostConstruct

我在 WildFly 8.2 应用程序服务器中使用来自 JavaEE 7 的上下文依赖注入 CDI 1.1 框架

我想在超class

@PostConstruct之后初始化子classes

所以我做了那样的事情

// case 1: it's working but it's not simple to understand

public class A {

    @PostConstruct
    protected void init() {
        System.out.println("A");
        afterInit();
    }

    protected void afterInit() {}

}

public class B extends A {

    @Override
    protected void afterInit() {
        System.out.println("B");
    }

}


public class C extends B {

    @Override
    protected void afterInit() {
        super.afterInit();
        System.out.println("C");
    }

}

因此init()方法将按顺序打印A、B、C

最好有一个 @AfterPostconstruct 注释来做同样的事情,但我没有找到

// case 2: dream code

public class A {

    @PostConstruct
    protected void init() {
        System.out.println("A");
    }

}

public class B extends A {

    @AfterPostConstruct  // pseudocode
    protected void afterInitB() {
        System.out.println("B");
    }

}


public class C extends B {

    @AfterPostConstruct // pseudocode
    protected void afterInitC() {
        System.out.println("C");
    }

}

我尝试覆盖 init() 但它不起作用(容器未调用 init()

// case 3 : code that is not working but it would be better than case 1

public class A {

    @PostConstruct
    protected void init() {
        System.out.println("A");
    }

}

public class B extends A {

    @Override
    protected void init() {
        super.init();
        System.out.println("B");
    }

}


public class C extends B {

    @Override
    protected void init() {
        super.init();
        System.out.println("C");
    }

} 

@PostConstruct 之后是否有更好(更简单)的方法来初始化子 classes?

根据 JSR 318 - Interceptors 1.2(也适用于 CDI 1.1)规范的 目标 Class 上声明的拦截器调用顺序部分:

Interceptor methods declared on the target class or its superclasses are invoked in the following order:

  • If a target class has superclasses, any interceptor methods defined on those superclasses are invoked, most general superclass first.
  • The interceptor method, if any, on the target class itself is invoked.

If an interceptor method is overridden by another method (regardless of whether that method is itself an interceptor method), it will not be invoked.

所以在你的用例中,你可以这样写:

public class A {

    @PostConstruct
    private void initA() {
        System.out.println("A");
    }
}

public class B extends A {

    @PostConstruct
    private void initB() {
        System.out.println("B");
    }
}

public class C extends B {

    @PostConstruct
    private void initC() {
        System.out.println("C");
    }
} 

然后按顺序打印:A、B、C。