<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oasis Feng &#187; Java</title>
	<atom:link href="http://blog.oasisfeng.com/category/develop/java-develop/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.oasisfeng.com</link>
	<description>Challenge your imagination!</description>
	<lastBuildDate>Tue, 13 Jul 2010 16:56:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>用Guice+Peaberry实现OSGi环境下的JIT注入</title>
		<link>http://blog.oasisfeng.com/2010/07/14/jit-injection-in-osgi-with-guice-and-peaberry/</link>
		<comments>http://blog.oasisfeng.com/2010/07/14/jit-injection-in-osgi-with-guice-and-peaberry/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 16:53:03 +0000</pubDate>
		<dc:creator>oasisfeng</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Guice]]></category>
		<category><![CDATA[JIT]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[Peaberry]]></category>

		<guid isPermaLink="false">http://blog.oasisfeng.com/?p=882</guid>
		<description><![CDATA[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&#40;LogService.class&#41;.toProvider&#40;Peaberry.service&#40;LogService.class&#41;.single&#40;&#41;&#41;; 如果转为JIT注入，则必须提供一个相应的Provider类。虽然Peaberry.service(&#8230;).single()返回的正是一个Provider，但鉴于Java注解只能用字面类（Literal Class），所以这里需要包装一下。我的办法是定义一个抽象的公共Provider，用反射去识别派生类的具体泛型类型： public abstract class JitProvider&#60;T&#62; implements Provider&#60;T&#62; &#123; &#160; &#160;protected JitProvider&#40;&#41; &#123; &#160; @SuppressWarnings&#40;&#34;unchecked&#34;&#41; &#160; final Class&#60;T&#62; clazz = &#40;Class&#60;T&#62;&#41; &#40;&#40;ParameterizedType&#41; getClass&#40;&#41;.getGenericSuperclass&#40;&#41;&#41;.getActualTypeArguments&#40;&#41;&#91;0&#93;; &#160; provider = Peaberry.service&#40;clazz&#41;.single&#40;&#41;.direct&#40;&#41;; &#160;&#125; &#160; &#160;@Override &#160;public T get&#40;&#41; &#123; &#160; return provider.get&#40;&#41;; &#160;&#125; &#160; &#160;@Inject &#160;protected void setInjector&#40;final Injector injector&#41; &#123; &#160; injector.injectMembers&#40;provider&#41;; &#160;&#125; [...]]]></description>
			<content:encoded><![CDATA[<p>Guice是一个Java下非常强大的依赖注入框架，相比其它同类框架，我更喜欢Guice这种“配置亦代码”的风格。除了开发友好性之外，Guice的过人之处还体现在它灵活的JIT(Just-in-time)注入上。利用@ProvidedBy()注解可以方便的为接口绑定定制的Provider，从而实现结合了动态逻辑的Lazy注入。</p>
<p>当Guice和OSGi框架碰撞到一起时，就会遇到一些观念上的矛盾：OSGi的动态生命周期在Guice本身的静态绑定下无法发挥其应有的作用，而Dynamic Service也无法方便的与Guice对接。好在开源社区已经有人意识到这些问题，并为两者搭起了一座鹊桥，这个项目就是“<a href="http://peaberry.googlecode.com/">Peaberry</a>”。</p>
<p>这两天在捣腾Peaberry时，发现它的设计主要是针对静态绑定，在与Guice的JIT注入一起用时，却还差那么一两块砖，于是自己把它给砌上了，顺便分享出来与大家交流一下。</p>
<p>按照Peaberry的用户手册，静态绑定一个DS服务的写法是在Module.configure()中使用：（以LogService接口为例）</p>
<div class="geshi no java5">
<ol>
<li class="li1">
<div class="de1">bind<span class="br0">&#40;</span>LogService.<span class="kw2">class</span><span class="br0">&#41;</span>.<span class="me1">toProvider</span><span class="br0">&#40;</span>Peaberry.<span class="me1">service</span><span class="br0">&#40;</span>LogService.<span class="kw2">class</span><span class="br0">&#41;</span>.<span class="me1">single</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
<p>如果转为JIT注入，则必须提供一个相应的Provider类。虽然Peaberry.service(&#8230;).single()返回的正是一个Provider，但鉴于Java注解只能用字面类（Literal Class），所以这里需要包装一下。我的办法是定义一个抽象的公共Provider，用反射去识别派生类的具体泛型类型：</p>
<div class="geshi no java5">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">abstract</span> <span class="kw2">class</span> JitProvider<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> <span class="kw2">implements</span> Provider<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">protected</span> JitProvider<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; @<span class="kw21">SuppressWarnings</span><span class="br0">&#40;</span><span class="st0">&quot;unchecked&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">final</span> Class<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> clazz = <span class="br0">&#40;</span>Class<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span><span class="br0">&#41;</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw26">ParameterizedType</span><span class="br0">&#41;</span> getClass<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getGenericSuperclass</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">getActualTypeArguments</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; provider = Peaberry.<span class="me1">service</span><span class="br0">&#40;</span>clazz<span class="br0">&#41;</span>.<span class="me1">single</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">direct</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;@<span class="kw21">Override</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">public</span> T get<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">return</span> provider.<span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;@Inject</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">protected</span> <span class="kw3">void</span> setInjector<span class="br0">&#40;</span><span class="kw2">final</span> Injector injector<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; injector.<span class="me1">injectMembers</span><span class="br0">&#40;</span>provider<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">private</span> <span class="kw2">final</span> Provider<span class="sy0">&lt;</span>T<span class="sy0">&gt;</span> provider<span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>具体使用JitProvider的接口以如下形式声明：</p>
<div class="geshi no java5">
<ol>
<li class="li1">
<div class="de1">@ProvidedBy<span class="br0">&#40;</span>Foo.<span class="kw39">Provider</span>.<span class="kw2">class</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">interface</span> Foo <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;&#8230;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw2">static</span> <span class="kw2">class</span> <span class="kw39">Provider</span> <span class="kw2">extends</span> JitProvider<span class="sy0">&lt;</span>Foo<span class="sy0">&gt;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>这样，所有使用Foo服务的Bundle都完全实现了即需即用，不必再像过去那样在每一个用到该服务的Bundle的Activator中事先进行一遍Peaberry繁琐的bind配置。经此精简优化，Peaberry的易用性得到了明显的提升，使用起来也更加直觉化了。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.oasisfeng.com/2010/07/14/jit-injection-in-osgi-with-guice-and-peaberry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在Google App Engine中使用泛域二级域名</title>
		<link>http://blog.oasisfeng.com/2010/01/30/use-wildcard-domains-in-google-appengine/</link>
		<comments>http://blog.oasisfeng.com/2010/01/30/use-wildcard-domains-in-google-appengine/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 10:40:39 +0000</pubDate>
		<dc:creator>oasisfeng</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[wildcard]]></category>

		<guid isPermaLink="false">http://blog.oasisfeng.com/?p=841</guid>
		<description><![CDATA[Google App Engine（以下简称GAE）除了支持自有的appspot.com域名外，借助Google Apps，它还允许用户配置自己的独立域名提供服务。但之前使用过独立域名的朋友可能都遇到过一个相同的困扰：你可以用指定一个特定的二级域名访问你的应用，但却无法使用泛域二级域名（wildcard sub-domain）。对泛域支持的社区呼声一直都很强烈，Google也声称将要支持这一特性，但却未给出具体的时间表。 前两天为了解决tb.ly的泛域二级域名，折腾了很久。因为虚拟主机服务商Dreamhost不对非Private Server用户支持DNS泛域解析，所以我不得不另谋它策。在GAE上的一次没头没脑的尝试，居然意外的让我发现GAE已悄然支持了泛域二级域名。配置过程稍微有些复杂，所以在这里完整整理出来，以tb.ly的真实案例，分享给各位研究GAE的朋友。 首先需要为你的域名（顶级或子域名均可，比如我的“tb.ly”）申请Google Apps服务，这是在GAE中配置独立域名的前提。申请免费的Standard版本即可。 然后就可以在GAE管理面板中选择Administration / Application Settings / Domain Setup / Add domain&#8230;，填入你的域名（比如“tb.ly”）。按照向导一步一步完成配置（可参考GAE的一篇教程），最后你会被带到Google Apps的应用配置界面，这里及可以为你的应用添加二级域名了。点“Add new URL”，会出现一个输入二级域名的输入框。Google并没有告诉你，其实这里只要输入“*”即可享受泛域二级域名了~ 完成上述配置后，试试在浏览器的地址栏输入任意一个二级域名（比如“oasis.tb.ly”），如果看到了你熟悉的应用界面，那么恭喜你，你已经成功完成了必要的配置！如果无法访问，也别灰心，很可能是由于你的DNS配置需要一些小小的调整。泛域域名需要在DNS配置中设定对应的泛域解析，具体而言，就是增加一条CNAME：*，指向ghs.l.google.com.（也可以是你自己为绑定ghs而创建的CNAME条目）。完成这项配置后，尝试ping一个任意二级域名，如果显示的回应主机名为ghs.l.google.com，就代表配置OK了。当然，如果回应主机没错，但ping的结果是timeout，那就涉及到另外一个复杂的国情问题，不在本文的讨论范畴内了。 至此为止，假设你已经成功的完成了上述步骤（还有任何我没有解释到的问题，欢迎留下评注或来信与我讨论）。那么下面我就拿tb.ly的例子演示一下如何在GAE的应用中识别和处理泛域二级域名：（我基本只用Java版，所以很抱歉不能同时覆盖Python的情形，不过相信这对熟悉GAE开发的朋友来说也不算是一个大问题） package ly.tb; import java.io.IOException; import java.net.URL; import java.util.Iterator; import java.util.NoSuchElementException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.appengine.repackaged.com.google.common.base.Splitter; public class SubDomainRedirector extends HttpServlet { @Override protected void doGet(final HttpServletRequest [...]]]></description>
			<content:encoded><![CDATA[<p>Google App Engine（以下简称GAE）除了支持自有的appspot.com域名外，借助Google Apps，它还允许用户配置自己的独立域名提供服务。但之前使用过独立域名的朋友可能都遇到过一个相同的困扰：你可以用指定一个特定的二级域名访问你的应用，但却无法使用泛域二级域名（wildcard sub-domain）。对泛域支持的<a href="http://code.google.com/p/googleappengine/issues/detail?id=113">社区呼声</a>一直都很强烈，Google也声称将要支持这一特性，但却未给出具体的时间表。</p>
<p>前两天为了解决tb.ly的泛域二级域名，折腾了很久。因为虚拟主机服务商Dreamhost不对非Private Server用户支持DNS泛域解析，所以我不得不另谋它策。在GAE上的一次没头没脑的尝试，居然意外的让我发现GAE已悄然支持了泛域二级域名。配置过程稍微有些复杂，所以在这里完整整理出来，以tb.ly的真实案例，分享给各位研究GAE的朋友。</p>
<p><span id="more-841"></span>首先需要为你的域名（顶级或子域名均可，比如我的“tb.ly”）<a href="http://www.google.com/apps/">申请Google Apps服务</a>，这是在GAE中配置独立域名的前提。申请免费的Standard版本即可。</p>
<p>然后就可以在GAE管理面板中选择Administration / Application Settings / Domain Setup / Add domain&#8230;，填入你的域名（比如“tb.ly”）。按照向导一步一步完成配置（可参考<a href="http://code.google.com/appengine/articles/domains.html">GAE的一篇教程</a>），最后你会被带到Google Apps的应用配置界面，这里及可以为你的应用添加二级域名了。点“Add new URL”，会出现一个输入二级域名的输入框。<strong>Google并没有告诉你，其实这里只要输入“*”即可享受泛域二级域名了~</strong></p>
<p>完成上述配置后，试试在浏览器的地址栏输入任意一个二级域名（比如“oasis.tb.ly”），如果看到了你熟悉的应用界面，那么恭喜你，你已经成功完成了必要的配置！如果无法访问，也别灰心，很可能是由于你的DNS配置需要一些小小的调整。泛域域名需要在DNS配置中设定对应的泛域解析，具体而言，就是增加一条CNAME：*，指向ghs.l.google.com.（也可以是你自己为绑定ghs而创建的CNAME条目）。完成这项配置后，尝试ping一个任意二级域名，如果显示的回应主机名为ghs.l.google.com，就代表配置OK了。当然，如果回应主机没错，但ping的结果是timeout，那就涉及到另外一个复杂的国情问题，不在本文的讨论范畴内了。</p>
<p>至此为止，假设你已经成功的完成了上述步骤（还有任何我没有解释到的问题，欢迎留下评注或来信与我讨论）。那么下面我就拿tb.ly的例子演示一下如何在GAE的应用中识别和处理泛域二级域名：（我基本只用Java版，所以很抱歉不能同时覆盖Python的情形，不过相信这对熟悉GAE开发的朋友来说也不算是一个大问题）</p>
<pre>package ly.tb;

import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.NoSuchElementException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.repackaged.com.google.common.base.Splitter;

public class SubDomainRedirector extends HttpServlet {

	@Override
	protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		final String host = new URL(req.getRequestURL().toString()).getHost();
		try {
			final String token = Splitter.on('.').split(host).iterator().next();
			if (token.equals("www"))
				resp.sendRedirect("<a href="http://tb.ly">http://tb.ly</a>");
			else
				resp.sendRedirect("http://" + token + ".taobao.com/");
		} catch(final Exception e) {
			resp.sendRedirect("<a href="http://tb.ly">http://tb.ly</a>");
		}
	}

	private static final long serialVersionUID = 1L;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.oasisfeng.com/2010/01/30/use-wildcard-domains-in-google-appengine/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Java容器中的泛型为什么不能Upcasting？</title>
		<link>http://blog.oasisfeng.com/2008/11/28/why-cannot-upcasting-generics-in-container/</link>
		<comments>http://blog.oasisfeng.com/2008/11/28/why-cannot-upcasting-generics-in-container/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 11:40:08 +0000</pubDate>
		<dc:creator>oasisfeng</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[cast]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Generics]]></category>
		<category><![CDATA[Upcast]]></category>

		<guid isPermaLink="false">http://blog.oasisfeng.com/?p=547</guid>
		<description><![CDATA[典型的例子是：List&#60;Object&#62; objects = (List&#60;Object&#62;) new List&#60;String&#62;() 可能很多人（包括我在内）起初都会认为这是无法理解的。那么请看下面的代码： objects.add(new Integer(7)); 假设前述的类型转换成立，那么这个objects实例中不就可以加入新的Integer项了？这等于是破坏了List&#60;String&#62;的约束。由于这个反例的存在，所以上述类型转换是不被Java所允许的。]]></description>
			<content:encoded><![CDATA[<p>典型的例子是：List&lt;Object&gt; objects = (List&lt;Object&gt;) new List&lt;String&gt;()</p>
<p>可能很多人（包括我在内）起初都会认为这是无法理解的。那么请看下面的代码：</p>
<p>objects.add(new Integer(7));</p>
<p>假设前述的类型转换成立，那么这个objects实例中不就可以加入新的Integer项了？这等于是破坏了List&lt;String&gt;的约束。由于这个反例的存在，所以上述类型转换是不被Java所允许的。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.oasisfeng.com/2008/11/28/why-cannot-upcasting-generics-in-container/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.406 seconds -->
