精华帖 (2) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-04-15
你这个情况还相对比较简单,可以看看assisted inject。对这中浅浅的就一层的动态注入还是可以应付的。
我一直比较纳闷的是,用pico/spring怎么解决这个问题呢? |
|
返回顶楼 | |
发表时间:2008-04-15
ajoo 写道 你这个情况还相对比较简单,可以看看assisted inject。对这中浅浅的就一层的动态注入还是可以应付的。
我一直比较纳闷的是,用pico/spring怎么解决这个问题呢? 我只是把我的问题简化了,实际问题里有好多参数,包括Object。 assisted inject我也刚刚看到,刚才在guice用户组里面也问了半天,不知道这个会不会整合到Guice 2.0里面去。 但是Assisted inject用起来并不简单,首先需要一个Factory interface,然后针对每一个create方法,要编写一个类(最好这个类实现一个接口)。这样搞起来,原来一个Factory类搞定的事情,用Guice加上AI可能要编写几十个类和接口才能搞得定。整体感觉还不如直接inject一个Factory类。 |
|
返回顶楼 | |
发表时间:2008-04-15
polygoncell 写道 ajoo 写道 你这个情况还相对比较简单,可以看看assisted inject。对这中浅浅的就一层的动态注入还是可以应付的。
我一直比较纳闷的是,用pico/spring怎么解决这个问题呢? 我只是把我的问题简化了,实际问题里有好多参数,包括Object。 assisted inject我也刚刚看到,刚才在guice用户组里面也问了半天,不知道这个会不会整合到Guice 2.0里面去。 但是Assisted inject用起来并不简单,首先需要一个Factory interface,然后针对每一个create方法,要编写一个类(最好这个类实现一个接口)。这样搞起来,原来一个Factory类搞定的事情,用Guice加上AI可能要编写几十个类和接口才能搞得定。整体感觉还不如直接inject一个Factory类。 factory interface 总归要要的。那么多参数,你一个一个手工new也一样麻烦啊。 但是“针对每一个create方法,要编写一个类”是什么意思? |
|
返回顶楼 | |
发表时间:2008-04-16
ajoo 写道 polygoncell 写道 ajoo 写道 你这个情况还相对比较简单,可以看看assisted inject。对这中浅浅的就一层的动态注入还是可以应付的。
我一直比较纳闷的是,用pico/spring怎么解决这个问题呢? 我只是把我的问题简化了,实际问题里有好多参数,包括Object。 assisted inject我也刚刚看到,刚才在guice用户组里面也问了半天,不知道这个会不会整合到Guice 2.0里面去。 但是Assisted inject用起来并不简单,首先需要一个Factory interface,然后针对每一个create方法,要编写一个类(最好这个类实现一个接口)。这样搞起来,原来一个Factory类搞定的事情,用Guice加上AI可能要编写几十个类和接口才能搞得定。整体感觉还不如直接inject一个Factory类。 factory interface 总归要要的。那么多参数,你一个一个手工new也一样麻烦啊。 但是“针对每一个create方法,要编写一个类”是什么意思? 这个是我在它的文档里读到的, http://publicobject.com/publicobject/assistedinject/javadocs/index.html 先是一个Factory: public interface PaymentFactory { Payment create(Date startDate, Money amount); } 然后针对这个create方法写一个类: public class RealPayment implements Payment { @AssistedInject public RealFoo(CreditService creditService, AuthService authService, @Assisted Date startDate, @Assisted Money amount) { ... } } 这里是binding: bind(FooFactory.class) .toProvider(FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class)); |
|
返回顶楼 | |
发表时间:2008-04-16
不是的。你那个类是本来就存在的。
assist inject要解决的问题是,一个类已经存在了(就象你的那个要动态注入Object的类),有些参数是由guice注入的,而有些是动态注入的。比如: public class Foo { public Foo(String id, Bar bar); // id是动态注入 } 这时候,如果没有guice或者任何di容器,你也要写一个factory接口: public class FooFactory { Foo createFoo(String id); } 然后在客户代码处: private final FooFactory factory; Foo foo1 = factory.createFoo("a"); Foo foo2 = factory.createFoo("b"); 如此,你还是一切都是依赖注入,而不必关心你不关心的Bar。 最后要手工实现FooFactory: class FooFactoryImpl implements FooFactory { private final Bar bar; public Foo createFoo(String id) { return new Foo(id, bar); } } assist inject帮你节省了最后一步,它用动态代理自动帮你生成FooFactoryImpl。 |
|
返回顶楼 | |
发表时间:2008-04-16
动态注入在spring里面是这样解决的,一次注入但是根据session的不同注入的是不同的Cart实例.
<bean id="cart" class="test.Cart" scope="session"> <aop:scoped-proxy /> </bean> guice一样可以用scope加proxy解决,要自己去定制. |
|
返回顶楼 | |
发表时间:2008-04-16
quaff 写道 动态注入在spring里面是这样解决的,一次注入但是根据session的不同注入的是不同的Cart实例.
<bean id="cart" class="test.Cart" scope="session"> <aop:scoped-proxy /> </bean> guice一样可以用scope加proxy解决,要自己去定制. 这个是用来解决 Scope不一注入的,同这个帖子讨论的不一样 |
|
返回顶楼 | |
发表时间:2008-04-16
yujiang 写道 quaff 写道 动态注入在spring里面是这样解决的,一次注入但是根据session的不同注入的是不同的Cart实例.
<bean id="cart" class="test.Cart" scope="session"> <aop:scoped-proxy /> </bean> guice一样可以用scope加proxy解决,要自己去定制. 这个是用来解决 Scope不一注入的,同这个帖子讨论的不一样 请看楼主说的第四条 |
|
返回顶楼 | |
发表时间:2008-04-16
ajoo 写道 不是的。你那个类是本来就存在的。
.... assist inject帮你节省了最后一步,它用动态代理自动帮你生成FooFactoryImpl。 噢,对对,你理解的对。 但是factory里面的create方法不总是这么简单的,有很多会是这样: class FooFactoryImpl implements FooFactory { private final Bar bar; public Foo createFoo(String id,String s, Object... o) { Foo foo = new Foo(id); // call some other API and do something with foo and other parameters, // for example decorate the Foo. return foo; } } 针对这样情况,如果使用Guice+AI,就得再继续编码,如果Foo是我们项目内部的类,那么可以将后续代码直接写进一个新的Foo constructor里去,例如: class Foo { .... @inject public Foo(String id,String s, Object... o) { this.id = id; // call some other API and do something with foo and other parameters, // for example decorate the Foo. } } 但是这样做有两个缺点,1. 第三方API直接和Foo POJO产生紧耦合。 2. Guice只允许一个constructor拥有@inject,也就是说使用了这个constructor,原来那个单纯使用String的constructor就没法用了。 考虑到这些情况,就得再写一个类,也就是我前面说的针对每一个create方法得再写一个类(以及接口),这个类可以直接继承Foo: class Foo1 extends Foo { .... @inject public Foo1(String id,String s, Object... o) { super(id); // call some other API and do something with foo and other parameters, // for example decorate the Foo. } } 这样factory接口不需要发生变化。 这个类也可以是一个Foo类的Holder(个人认为这样更好): class FooHolder { private Foo foo; // define some property from the other API @inject public Foo1(String id,String s, Object... o) { foo = new Foo(id); // call some other API and do something with foo and other parameters, // for example decorate the Foo. } // Getters } 这样做避免了不必要的继承,FooHolder不但可以提供Foo,而且可以提供需要的其他对象。但是缺点是我们需要修改Factory中ocreate方法的返回值: public interface FooFactory { FooHolder createFoo(String id); } 并且将FooHolder而非Foo注入到其他类中去。 但是这样一来,原来只是一个大的Factory类,现在就变成了一个Factory接口,加上一堆小的Holder类及其接口,类的数量增加了很多。整体感觉还是保留Factory类,然后将Factory注入到需要它的地方显得更便捷。 |
|
返回顶楼 | |
发表时间:2008-04-16
polygoncell 写道 非常感谢,写了这么一大堆。:-)
这种做法和我考虑的一样,问题是这样也太麻烦了吧! 只是 new FooContainer(new Foo(true, false))和new FooContainer(new Foo(false, true))就能搞定的,结果用Guice写了这么多代码。 还有就是关于String的那个问题还存在。我再举例说明一下。在程序的某处需要Foo对象,例如Foo("ABC"), 过段时间,在其他地方又需要Foo("DEF"), 再过段时间,又需要Foo("XZY")就这样继续下去。。。。。。 我怎么用一个Foo类类实现这些映射?这些String之间并没有任何规律可循。 可以试试objot2的ioc容器 Container stub = new Factory() { @Override protected Object doBind(Class<?> c, Bind b) throws Exception { if (c == Foo.class) return b.mode(Inject.Set.class); // 通过set来指定对象 return b; } }.bind(Foo.class).create(null); Container c1 = stub.create(); c1.set(Foo.class, new Foo(true, false)); Container c2 = stub.create(); c2.set(Foo.class, new Foo(false, true)); 这样c1、c2就可以绑定Foo到不同的对象上 不同时候要不同Foo时,如果流程上的先后能确定,那可以: Container c = stub.create(); ... c.set(Foo.class, foo1); c.get(FooClient1.class); ... c.set(Foo.class, foo2); c.get(FooClient2.class); ... 不过那些在set前就由容器创建的对象(例如已经获取的singleton)看不到set的东西 |
|
返回顶楼 | |