| 14 | |
| 2010.7 |
Guice是一个Java下非常强大的依赖注入框架,相比其它同类框架,我更喜欢Guice这种“配置亦代码”的风格。除了开发友好性之外,Guice的过人之处还体现在它灵活的JIT(Just-in-time)注入上。利用@ProvidedBy()注解可以方便的为接口绑定定制的Provider,从而实现结合了动态逻辑的Lazy注入。
当Guice和OSGi框架碰撞到一起时,就会遇到一些观念上的矛盾:OSGi的动态生命周期在Guice本身的静态绑定下无法发挥其应有的作用,而Dynamic Service也无法方便的与Guice对接。好在开源社区已经有人意识到这些问题,并为两者搭起了一座鹊桥,这个项目就是“Peaberry”。
这两天在捣腾Peaberry时,发现它的设计主要是针对静态绑定,在与Guice的JIT注入一起用时,却还差那么一两块砖,于是自己把它给砌上了,顺便分享出来与大家交流一下。
按照Peaberry的用户手册,静态绑定一个DS服务的写法是在Module.configure()中使用:(以LogService接口为例)
-
bind(LogService.class).toProvider(Peaberry.service(LogService.class).single());
如果转为JIT注入,则必须提供一个相应的Provider类。虽然Peaberry.service(…).single()返回的正是一个Provider,但鉴于Java注解只能用字面类(Literal Class),所以这里需要包装一下。我的办法是定义一个抽象的公共Provider,用反射去识别派生类的具体泛型类型:
-
public abstract class JitProvider<T> implements Provider<T> {
-
-
protected JitProvider() {
-
@SuppressWarnings("unchecked")
-
final Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
-
provider = Peaberry.service(clazz).single().direct();
-
}
-
-
@Override
-
public T get() {
-
return provider.get();
-
}
-
-
@Inject
-
protected void setInjector(final Injector injector) {
-
injector.injectMembers(provider);
-
}
-
-
private final Provider<T> provider;
-
}
具体使用JitProvider的接口以如下形式声明:
-
@ProvidedBy(Foo.Provider.class)
-
public interface Foo {
-
…
-
static class Provider extends JitProvider<Foo> {}
-
}
这样,所有使用Foo服务的Bundle都完全实现了即需即用,不必再像过去那样在每一个用到该服务的Bundle的Activator中事先进行一遍Peaberry繁琐的bind配置。经此精简优化,Peaberry的易用性得到了明显的提升,使用起来也更加直觉化了。
| 30 | |
| 2010.1 |
Google App Engine(以下简称GAE)除了支持自有的appspot.com域名外,借助Google Apps,它还允许用户配置自己的独立域名提供服务。但之前使用过独立域名的朋友可能都遇到过一个相同的困扰:你可以用指定一个特定的二级域名访问你的应用,但却无法使用泛域二级域名(wildcard sub-domain)。对泛域支持的社区呼声一直都很强烈,Google也声称将要支持这一特性,但却未给出具体的时间表。
前两天为了解决tb.ly的泛域二级域名,折腾了很久。因为虚拟主机服务商Dreamhost不对非Private Server用户支持DNS泛域解析,所以我不得不另谋它策。在GAE上的一次没头没脑的尝试,居然意外的让我发现GAE已悄然支持了泛域二级域名。配置过程稍微有些复杂,所以在这里完整整理出来,以tb.ly的真实案例,分享给各位研究GAE的朋友。
| 28 | |
| 2008.11 |
典型的例子是:List<Object> objects = (List<Object>) new List<String>()
可能很多人(包括我在内)起初都会认为这是无法理解的。那么请看下面的代码:
objects.add(new Integer(7));
假设前述的类型转换成立,那么这个objects实例中不就可以加入新的Integer项了?这等于是破坏了List<String>的约束。由于这个反例的存在,所以上述类型转换是不被Java所允许的。
