首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能为生产者方法代理非JSR299 bean

不能为生产者方法代理非JSR299 bean
EN

Stack Overflow用户
提问于 2015-11-12 07:01:35
回答 1查看 454关注 0票数 1

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

我把这解释为,如果我想让一个带有带参数的构造函数的bean成为可注入的,我可以通过使用生产者方法来实现。

然而,当我这样做时,我在部署时得到了以下异常:

代码语言:javascript
复制
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()]. 

下面是制作人:

代码语言:javascript
复制
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);
    }
}

其用法如下:

代码语言:javascript
复制
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());
    }

 }

我是不是漏掉了什么很明显的东西?

EN

回答 1

Stack Overflow用户

发布于 2015-11-13 17:54:44

最简单的解决方案是将作用域从@ApplicationScoped更改为@Singleton

代码语言:javascript
复制
import javax.inject.Singleton;

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

有关说明,您可以查看this SO answer

顺便说一句:与@Singleton伪作用域相比,通常首选普通作用域@ApplicationScoped。为什么?例如,因为这样的bean的串行化+反串行化将完美地工作。但在日常工作中,有时我们会遇到第三方类,是不可代理的,我们无法更改它。因此,我们有可能的解决方案:

  • 使用@Singleton bean作为接口,而不是具体的bean(在生产者方法返回类型和普通代码内部)。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33661471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档