gpt4 book ai didi

java - 非 JSR299 bean 无法代理生产者方法

转载 作者:太空宇宙 更新时间:2023-11-04 13:14:40 27 4
gpt4 key购买 nike

我知道,如果通过生产者方法实例化,不符合 JSP-299 的类可以用于注入(inject)。

我对此的解释是,如果我想使用带有参数的构造函数来注入(inject)一个 bean,我可以通过使用生产者方法来实现。

但是,当我这样做时,我在部署时遇到以下异常:

2015-11-11T21:35:12.099+0000|Grave: Exception during lifecycle processing
org.glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001435 Normal scoped bean class org.....MongoConfiguration is not proxyable because it has no no-args constructor - Producer Method [MongoConfiguration] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces @ApplicationScoped public org.....PropertiesProducer.produceMongoConfiguration()].

这是制作人:

public class PropertiesProducer {

private static final String PROPERTIES_FILE = "mongo.properties";

private Properties properties = new Properties();

public static final String DATABASE_NAME = "database.name";
public static final String PORT = "database.port";
public static final String HOST = "database.host";
public static final String USERNAME = "database.username";
public static final String PASSWORD = "database.password";

@Produces
@ApplicationScoped
public MongoConfiguration produceMongoConfiguration(){

final InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(PROPERTIES_FILE);
if (in == null) {
return new MongoConfiguration(properties);
}
try {
properties.load(in);
} catch (IOException e) {
throw new RuntimeException("Failed to load properties", e);
}
finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
// don't care
}
}

return new MongoConfiguration(properties);
}
}

用法如下:

public class MongoDatastore {

@Inject
MongoConfiguration mongoConfiguration;

@Inject
MongoClient mongoClient;
Datastore datastore;

@PostConstruct
private void setupDatastore() {
Morphia morphia = new Morphia();
datastore = morphia.createDatastore(mongoClient, mongoConfiguration.getDatabaseName());
}

}

我是否错过了一些非常明显的事情?

最佳答案

最简单的解决方案是将范围从 @ApplicationScoped 更改为 @Singleton:

import javax.inject.Singleton;

@Produces
@Singleton
public MongoConfiguration produceMongoConfiguration(){
// ...
return new MongoConfiguration(properties);
}

要了解详情,您可以查看 this SO answer .

顺便说一句:普通作用域 @ApplicationScoped 通常优于 @Singleton 伪作用域。为什么?例如。因为这样的 bean 的序列化+反序列化将完美地工作。但在日常工作中,有时我们会遇到不可代理的第3部分类,并且我们无法更改它。所以我们可能的解决方案是:

  • 使用@Singleton伪作用域。
  • 创建一个接口(interface)并使用它来代替具体的 bean(在生产者方法返回类型和普通代码中)。

关于java - 非 JSR299 bean 无法代理生产者方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33661471/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com