Как внедрить вложенный (внутренний) нестатический класс в micronaut?

#java #dependency-injection #inner-classes #micronaut

#java #внедрение зависимостей #внутренние классы #micronaut

Вопрос:

  • версия micronaut: 2.2.1
  • версия java: 11
  • ОС: Windows 10

Мой код выглядит следующим образом:

 import io.micronaut.context.annotation.Prototype;

import javax.inject.Inject;
import javax.inject.Singleton;

@Singleton
public class ParentObject {
    @Inject ChildClass childClass;
    String keyVar = 'FOO';

    public void parentFoo() {
        System.out.println("I am foo in parent class");
        childClass.childFoo();
    }

    @Prototype
    class ChildClass  {
        public ChildClass() {}

        public void childFoo() {
            System.out.println("I am foo in child class. keyVar is"  ParentObject.this.keyVar);
        }
    }
}
 

Процесс компиляции в порядке. Но при выполнении кода возникают следующие ошибки:

 Message: com.jcarxmate.test.ParentObject$ChildClass: method <init>()V not found
Path Taken: CoreCommand.testController --> TestController.parentObject --> ParentObject.childClass
    at picocli.CommandLine$DefaultFactory.create(CommandLine.java:5201)
    at picocli.CommandLine$Model$CommandUserObject.getInstance(CommandLine.java:11160)
    at picocli.CommandLine$Model$CommandSpec.userObject(CommandLine.java:5928)
    at picocli.CommandLine$Interpreter.clear(CommandLine.java:12323)
    at picocli.CommandLine$Interpreter.parse(CommandLine.java:12364)
    at picocli.CommandLine$Interpreter.parse(CommandLine.java:12259)
    at picocli.CommandLine.parseArgs(CommandLine.java:1458)
    at picocli.CommandLine.execute(CommandLine.java:2057)
    at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:137)
    at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:114)
    at com.jcarxmate.CoreCommand.main(CoreCommand.java:29)
Caused by: io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type  [com.jcarxmate.test.ParentObject]

Message: com.jcarxmate.test.ParentObject$ChildClass: method <init>()V not found
Path Taken: CoreCommand.testController --> TestController.parentObject --> ParentObject.childClass
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1925)
    at io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2424)
    at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2339)
    at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2311)
    at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1245)
    at io.micronaut.context.AbstractBeanDefinition.getBeanForField(AbstractBeanDefinition.java:1441)
    at io.micronaut.context.AbstractBeanDefinition.getBeanForField(AbstractBeanDefinition.java:1203)
    at com.jcarxmate.test.$ParentObjectDefinition.injectBean(Unknown Source)
    at com.jcarxmate.test.$ParentObjectDefinition.build(Unknown Source)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1898)
    at io.micronaut.context.DefaultBeanContext.createAndRegisterSingletonInternal(DefaultBeanContext.java:2679)
    at io.micronaut.context.DefaultBeanContext.createAndRegisterSingleton(DefaultBeanContext.java:2665)
    at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2337)
    at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2311)
    at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1245)
    at io.micronaut.context.AbstractBeanDefinition.getBeanForField(AbstractBeanDefinition.java:1441)
    at io.micronaut.context.AbstractBeanDefinition.getBeanForField(AbstractBeanDefinition.java:1203)
    at com.jcarxmate.test.$TestControllerDefinition.injectBean(Unknown Source)
    at com.jcarxmate.test.$TestControllerDefinition.build(Unknown Source)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1898)
    at io.micronaut.context.DefaultBeanContext.createAndRegisterSingletonInternal(DefaultBeanContext.java:2679)
    at io.micronaut.context.DefaultBeanContext.createAndRegisterSingleton(DefaultBeanContext.java:2665)
    at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2337)
    at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2311)
    at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1245)
    at io.micronaut.context.AbstractBeanDefinition.getBeanForField(AbstractBeanDefinition.java:1441)
    at io.micronaut.context.AbstractBeanDefinition.getBeanForField(AbstractBeanDefinition.java:1203)
    at com.jcarxmate.$CoreCommandDefinition.injectBean(Unknown Source)
    at com.jcarxmate.$CoreCommandDefinition.build(Unknown Source)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1898)
    at io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2424)
    at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2339)
    at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2311)
    at io.micronaut.context.DefaultBeanContext.findBean(DefaultBeanContext.java:1266)
    at io.micronaut.context.DefaultBeanContext.findBean(DefaultBeanContext.java:744)
    at io.micronaut.context.BeanLocator.findOrInstantiateBean(BeanLocator.java:163)
    at io.micronaut.configuration.picocli.MicronautFactory.create(MicronautFactory.java:73)
    at picocli.CommandLine$DefaultFactory.create(CommandLine.java:5197)
    ... 10 more
Caused by: java.lang.NoSuchMethodError: com.jcarxmate.test.ParentObject$ChildClass: method <init>()V not found
    at com.jcarxmate.test.$ParentObject$ChildClassDefinition.build(Unknown Source)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1898)
    ... 47 more
 

Если я удалю @Inject из строки @Inject ChildClass childClass; и добавлю childClass = new ChildClass(); , как показано ниже, это сработает:

 public void parentFoo() {
    System.out.println("I am foo in parent class");
    childClass = new ChildClass();
    childClass.childFoo();
}
 

Но я все еще надеюсь использовать @Inject, если это возможно. Однако я не могу использовать вложенный статический класс, потому ChildClass что должен обращаться к переменным и методам в родительском классе.

Итак, есть какие-либо предложения? Спасибо

Комментарии:

1. @Inject экземпляр родительского класса в (вложенный статический) дочерний класс?

2. Означает ли тот факт, что вы отметили ChildClass с @Prototype помощью, что вы вводите его в другие места, кроме показанного?

3. @JeffScottBrown Дочерний объект используется только в ParentObject и в ParentObject