2013-05-22 29 views
2

我是一个guice新手,试图找出如何使用FactoryModuleBuilder实现guice中的辅助注入。我咨询了guice java文档来实现FactoryModuleBuilder在guice中使用FactoryModuleBuilder中的辅助注入 - 工厂注入未完成

我完全按照它在文档中所说的完成了一切。 它不注入工厂。 我提到了这个堆栈溢出问题:Guice AssistedInject won't inject the factory 有同样的问题。 它讨论了构造函数注入问题之前的字段注入。我跟着它,我想使用调用者类调用父类,但我仍然得到空指针异常。这里出了什么问题?

主叫类

public class MAIN { 

    @Inject private static MyFactory factory; 

    public static void main(String[] args){ 
     ParentClass newbie = new ParentClass(factory); 
    } 
} 

我仍然得到异常:

Exception in thread "main" java.lang.NullPointerException 
    at com.pkg.ParentClass.<init>(ParentClass.java:19) 
    at com.pkg.MAIN.main(MAIN.java:10) 

父类

public class ParentClass { 

    private final Foo test; 
    @Inject 
    public ParentClass(MyFactory factory){ 
     test = factory.create(new HashMap<String,Object>()); 
    } 
} 

模块实现:ParentModu勒

public class ParentModule extends AbstractModule{ 

    @Override 
    protected void configure() { 
     install(new FactoryModuleBuilder() 
       .implement(Foo.class, FooImpl.class) 
       .build(MyFactory.class)); 
    } 

} 

工厂接口:MyFactory

public interface MyFactory { 

    Foo create(Map<String,Object> map); 
} 

类接口:富

public interface Foo{ 
} 

类别:FooImpl

public class FooImpl implements Foo { 

    private final Map<String,Object> mapA; 
    @AssistedInject 
    public FooImpl(@Assisted Map<String,Object> map){ 

     mapA=map; 
    } 

} 

回答

3

这里有两个问题。

首先也是最重要的,你不是在任何地方创建Injector。显然,没有喷油器什么都不会起作用。你必须使用你的模块创建一个喷油器实例:

Injector injector = Guice.createInjector(new ParentModule()); 

你的第二个问题是,你希望你的工厂注入静态字段:

@Inject private static MyFactory factory; 

虽然吉斯可以用静态字段工作,如果你明确地告诉它,这被认为是非常糟糕的做法。除非您使用一些遗留代码,否则不应该注入静态字段。

你真正想要的是这样的:

public class Main { 
    @Inject 
    private MyFactory factory; 

    public void run() { 
     ParentClass newbie = new ParentClass(factory); 
    } 

    public static void main(String[] args) { 
     Injector injector = Guice.createInjector(new ParentModule()); 
     Main main = injector.getInstance(Main.class); 
     main.run(); 
    } 
} 

注意,现在程序入口点(main)是创建一个注射器,然后用它来创建一个实例Main,这将有其字段自动注入。然后在执行实际工作的实例上调用方法run()

但是,请注意,这是所有真正有效的只有出于辅助注射的说明目的。你不应该结构你这样的真实代码。例如,您使用new运算符来创建其构造函数用@Inject进行注释的类。千万不要这样做!如果您将某些类别(即其构造函数或字段)标记为@Inject,则应通过注入方式将此类别用于只有。您Main代码可以缩短为以下:

public class Main { 
    public static void main(String[] args) { 
     Injector injector = Guice.createInjector(new ParentModule()); 
     ParentClass newbie = injector.getInstance(ParentClass.class); 
    } 
} 

这里newbie将自动接收的MyFactory实例到它的构造,因为它与@Inject注解。

而且我已经写过静力学。

+0

感谢弗拉基米尔的帮助,但这仍然没有奏效。它给main类中的createInjector中的javax.inject.Provider提供noClassDefFoundError – sachi1325

+0

@ sachi1325,这是你的类路径的一个问题。 Guice依赖于两个库,aopalliance和javax.inject。最后一个似乎从你的classpath中丢失了。我建议使用maven,你可能不会错过任何传递依赖。 –

+0

感谢弗拉基米尔,它的作品! :) – sachi1325