java - 为什么我必须在此示例中为 Weld 添加私有(private)构造函数?

标签 java cdi jboss-weld weld

我正在尝试 Weld 。鉴于以下先决条件...

public interface Printer {
    void print(Job job) throws IOException;

    interface Job { void feed(PrintStream out); }
}

@Qualifier
@Target({ METHOD, FIELD, PARAMETER, TYPE })
@Retention(RUNTIME)
public @interface StandardOutput { }

@Qualifier
@Target({ METHOD, FIELD, PARAMETER, TYPE })
@Retention(RUNTIME)
public @interface StandardError { }

...我想提供两个标准实例,一个用于标准输出流,一个用于标准错误流(JSE 环境):

public class PrintStreamPrinter implements Printer {

    private final PrintStream out;

    @Produces static final @StandardOutput PrintStreamPrinter
            stdout = new PrintStreamPrinter(System.out);

    @Produces static final @StandardError PrintStreamPrinter
            stderr = new PrintStreamPrinter(System.err);

    private PrintStreamPrinter() { throw new AssertionError(); }

    public PrintStreamPrinter(final PrintStream out) {
        this.out = Objects.requireNonNull(out);
    }

    public void print(final Job job) throws IOException {
        job.feed(out);
        if (out.checkError()) throw new IOException();
    }
}

现在我可以像这样使用它:

@Inject @StandardOutput Printer printer;

并从此快乐地使用它。

但是,如果我从 PrintStreamPrinter 类中删除没有参数的无用私有(private)构造函数,则会失败。我花了一段时间才弄清楚这一点,但我不知道为什么。显然,该实现从未被调用,那么为什么它首先必须存在呢?请注意,我在这里使用 @Dependent 范围,因此无需创建客户端代理。

这是我在删除无用的私有(private)构造函数后从 Weld SE 2.0.1.Final 得到的异常:

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Printer] with qualifiers [@StandardOutput] at injection point [[BackedAnnotatedField] @Inject @StandardOutput private com.company.mavenproject1.Main.printer]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:404)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:326)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:177)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:208)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:520)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:70)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

更有趣的是:如果存在私有(private)构造函数,Weld 日志会告诉我:

WELD-000106 Bean: Producer Field [PrintStreamPrinter] with qualifiers [@StandardOutput @Any] declared as [[BackedAnnotatedField] @Produces @StandardOutput final static com.company.mavenproject1.PrintStreamPrinter.stdout]
WELD-000106 Bean: Producer Field [PrintStreamPrinter] with qualifiers [@StandardError @Any] declared as [[BackedAnnotatedField] @Produces @StandardError final static com.company.mavenproject1.PrintStreamPrinter.stderr]

当构造函数被删除时,这些行就会丢失。

这是错误还是功能?

最佳答案

为了让 CDI 正确代理您的类,您必须有一个无参数构造函数(认为它必须是公共(public)的,但可以是实现)或一个标有 @Inject 的构造函数。

看看the specification source .

关于java - 为什么我必须在此示例中为 Weld 添加私有(private)构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17048024/

相关文章:

java - 解码转义的unicode

Java方法calculate ("2.002*1000")//返回2001.999999999999

jax-rs - 使用 RESTEasy、Weld 和 Wildfly 失败的 @Inject 对象

jakarta-ee - 在由生产者方法创建的 bean 中,cdi 注入(inject)的依赖项解析为 null

java-ee-6 - CDI - 观察容器事件

hibernate - 在tomcat中使用生产者注入(inject)EntityManager

java - 不同项目中的Bean接口(interface)和Bean实现

java - XPages:从 managedBean 读取私有(private)属性失败

java - CDI GenericDAO 和自定义实现

java - Spring 请求映射和主题