首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >“辅助”工厂的输出应该是@Singleton

“辅助”工厂的输出应该是@Singleton
EN

Stack Overflow用户
提问于 2012-08-07 10:56:28
回答 1查看 1.9K关注 0票数 2

我目前正在尝试在一个小应用程序中使用Google Guice-3.0。

运行此应用程序时,系统会提示用户输入其姓名和密码。因为这些信息直到运行时才知道,所以我使用AssistedInject来实现我的User实例化。

这就是我的UserFactory的用武之地。它为User提供了方法

代码语言:javascript
代码运行次数:0
运行
复制
public User create(@Assisted("Username") String username, 
                   @Assisted("Password") String password);

User类在程序开始时(在用户输入之后)通过

代码语言:javascript
代码运行次数:0
运行
复制
User user = getInjector().getInstance(UserFactory.class).create(username, password);

我想在应用程序的整个生命周期中使用这个实例。我已经将作用域设置为@Singleton

然而,问题是,我只得到错误。Guice抱怨我在调用

代码语言:javascript
代码运行次数:0
运行
复制
User user = getInjector().getInstance( User.class );

如果我将一个bind( User.class );添加到configure方法中,就会出现一个错误,说明没有对注释@Assisted进行声明(因为您可以在参数前面放置注释来唯一地标识它们- Guice可能认为它是参数之一,并要求设置依赖项(例如

代码语言:javascript
代码运行次数:0
运行
复制
bind( String.class ).annotatedWith( Assisted.class ).toInstance( username );

但是这不是一个可以工作的东西(也许它可以通过静态引用来工作,但是为什么要使用Guice呢?

这里有一个你可以编译的例子。注释的代码会导致错误。特别是最后两行让我很恼火。

代码语言:javascript
代码运行次数:0
运行
复制
public class KSKB {

    @Singleton
    public static class User {

        public final String name;

        @Inject
        public User(@Assisted("Username") String username) {
            this.name = username;
        }

        public static interface Factory {
            public User create(@Assisted("Username") String username);
        }
    }

    public static void main(String... args) {
        Injector injector = Guice.createInjector(new AbstractModule() {

            @Override
            protected void configure() {
                install(new FactoryModuleBuilder().build(User.Factory.class));
                // bind( User.class );
            }

        });
        User user = injector.getInstance(User.Factory.class).create("Guice");
        System.out.println(user.name);

        // user = injector.getInstance( User.class ); // doesn't work - throws Exception!!
        // System.out.println( user.name );
    }
}
EN

回答 1

Stack Overflow用户

发布于 2012-08-20 22:15:26

辅助注入的输出不是注入--它是自动连接的工厂(可悲的是,这个工厂的名字很糟糕)。

AssistedInject生成的是一个工厂--工厂可以是单例的。但它是一个工厂,所以它的工作是创建对象,比如User对象。Factory的内部结构并没有设置为让它创建单值对象。一般来说,值对象不是单例对象--您在这里使用一个对象作为“上下文”而不是数据,因此您有一个特殊情况。

此外,您的情况更加特殊,因为您希望在guice运行之前预先验证数据库中的数据。这个用户完全是上下文,而不是数据,所以不要使用工厂来创建它。手动创建它,如果您需要在Guice绑定的系统中的其他地方使用它,那么在Guice外部创建它,并将其作为DatabaseCredentials对象或类似对象传递到模块中。

为了正确地帮助你,我们需要看到一个更大的设计概念,但我的感觉是,你没有清楚地考虑到协作者/服务、值类型、上下文/配置等之间的区别,而混乱主要是因为“用户”这个词在这里被重载了。是的,它是一个“用户”,但数据库用户与系统中的其他用户不是同一类型的用户-即使它在结构上相同,它意味着不同的东西,具有不同的生命周期,等等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11838634

复制
相关文章

相似问题

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