代码之家  ›  专栏  ›  技术社区  ›  user2175783

如何将注入的bean传递给另一个注入的对象?[副本]

  •  2
  • user2175783  · 技术社区  · 7 年前

    在托管bean中, @PostConstruct 在常规Java对象构造函数之后调用。

    我为什么要用 通过bean而不是常规构造函数本身进行初始化?

    0 回复  |  直到 16 年前
        1
  •  455
  •   Jasper wontondon    14 年前
    • 因为当调用构造函数时,bean还没有初始化,即没有注入依赖项。在 @PostConstruct 方法bean已完全初始化,您可以使用依赖项。

    • @施工后 将只调用一次。

        2
  •  113
  •   Andrea Ligios    7 年前

    这个 主要的 问题是:

    在构造函数中,依赖项的注入尚未发生*

    *显然不包括构造函数注入


    现实世界的例子:

    public class Foo {
    
        @Inject
        Logger LOG;
    
        @PostConstruct
        public void fooInit(){
            LOG.info("This will be printed; LOG has already been injected");
        }
    
        public Foo() {
            LOG.info("This will NOT be printed, LOG is still null");
            // NullPointerException will be thrown here
        }
    }
    

    重要 : @PostConstruct @PreDestroy removed in Java 11 .

    要继续使用它们,您需要添加 javax.annotation-api 你的依赖关系。

    马文

    <!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.3.2</version>
    </dependency>
    

    格拉德尔

    // https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
    compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
    
        3
  •  68
  •   skaffman    16 年前

    @PostConstruct

    但是,如果类使用setter方法注入依赖项,则类的构造函数无法完全初始化对象,有时需要在调用所有setter方法之后执行一些初始化,因此 @施工后 .

        4
  •  11
  •   Humoyun Ahmad    8 年前

    考虑以下场景:

    public class Car {
      @Inject
      private Engine engine;  
    
      public Car() {
        engine.initialize();  
      }
      ...
    }
    

    由于Car必须在字段注入之前实例化,因此在构造函数执行期间注入点引擎仍然为null,从而导致NullPointerException。

    这个问题可以通过以下两种方法来解决 JSR-330 Dependency Injection for Java 用于Java@PostConstruct方法注释的构造函数注入或jsr250公共注释。

    @施工后

    JSR-250定义了javase6中包含的一组公共注释。

    PostConstruct注释用于需要 在完成依赖注入后执行 初始化。必须在放置类之前调用此方法 投入使用。必须在所有 支持依赖注入。

    JSR-250第2.5章javax.annotation.PostConstruct

    @PostConstruct注释允许在实例化实例并执行所有注入之后执行方法的定义。

    public class Car {
      @Inject
      private Engine engine;  
    
      @PostConstruct
      public void postConstruct() {
        engine.initialize();  
      }
      ...
    } 
    

    构造后方法的处理很简单,只需找到用@PostConstruct注释的所有方法,然后依次调用它们。

    private  void processPostConstruct(Class type, T targetInstance) {
      Method[] declaredMethods = type.getDeclaredMethods();
    
      Arrays.stream(declaredMethods)
          .filter(method -> method.getAnnotation(PostConstruct.class) != null) 
          .forEach(postConstructMethod -> {
             try {
               postConstructMethod.setAccessible(true);
               postConstructMethod.invoke(targetInstance, new Object[]{});
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {      
              throw new RuntimeException(ex);
            }
          });
    }
    

        5
  •  1
  •   struberg    14 年前

    此外,每当涉及某种代理或远程处理时,基于构造函数的初始化将无法按预期工作。