google guice 入门教程07 -凯发k8网页登录

关注后端架构、中间件、分布式和并发编程

   :: 凯发k8网页登录首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  111 随笔 :: 10 文章 :: 2680 评论 :: 0 trackbacks

4 整合第三方组件

在《》 中我们看到了guice 整合struts 2的应用。本章节继续讨论guice整合其它第三方组件的应用。

本章节重点谈guice与dwr和spring的整合。

4.1 整合dwr

dwr作为ajax远程调用的服务端得到了很多程序员的追捧,在dwr的2.x版本中已经集成了guice的插件。

老套了,我们还是定义一个helloworld的服务吧,哎,就喜欢helloworld,不怕被别人骂!


1 public interface helloworld {
2 
3     string sayhello();
4 
5     date getsystemdate();
6 }
7 

然后写一个简单的实现吧。


 1 public class helloworldimpl implements helloworld {
 2 
 3     @override
 4     public date getsystemdate() {
 5         return new date();
 6     }
 7 
 8     @override
 9     public string sayhello() {
10         return "hello, guice";
11     }
12 }
13 

然后是与dwr有关的东西了,我们写一个dwr的listener来注入我们的模块。


 1 package cn.imxylz.study.guice.web.dwr;
 2 
 3 import org.directwebremoting.guice.dwrguiceservletcontextlistener;
 4 
 5 /**
 6  * @author xylz (www.imxylz.cn)
 7  * @version $rev: 105 $
 8  */
 9 public class mydwrguiceservletcontextlistener extends dwrguiceservletcontextlistener{
10 
11     @override
12     protected void configure() {
13         bindremotedas("helloworld", helloworld.class).to(helloworldimpl.class).aseagersingleton();
14     }
15 }
16 

这里使用bindremotedas来将凯发k8网页登录的服务开放出来供dwr远程调用。

剩下的就是修改web.xml,需要配置一个dwr的servlet并且将我们的listener加入其中。看看全部的内容。


 1 xml version="1.0" encoding="utf-8"?>
 2 <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
 3     xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 4     version="2.5">
 5 
 6     <display-name>guice-dwrdisplay-name>
 7     <description>xylz study project - guicedescription>
 8 
 9     <listener>
10         <listener-class>cn.imxylz.study.guice.web.dwr.mydwrguiceservletcontextlistener
11         listener-class>
12     listener>
13     <servlet>
14         <servlet-name>dwr-invokerservlet-name>
15         <servlet-class>org.directwebremoting.guice.dwrguiceservletservlet-class>
16         <init-param>
17           <param-name>debugparam-name>
18           <param-value>trueparam-value>
19         init-param>
20     servlet>
21     <servlet-mapping>
22         <servlet-name>dwr-invokerservlet-name>
23         <url-pattern>/dwr/*url-pattern>
24     servlet-mapping>
25 
26 web-app>
27 

非常简单,也非常简洁,其中dwrguiceservlet的debug参数只是为了调试方便才开放的,实际中就不用写了。

好了,看看我们的效果。

 1 <html>
 2 <head><title>dwr - test (www.imxylz.cn) title>
 3   <script type='text/javascript' src='/guice-dwr/dwr/interface/helloworld.js'>script>
 4   <script type='text/javascript' src='/guice-dwr/dwr/engine.js'>script>
 5   <script type='text/javascript' src='/guice-dwr/dwr/util.js'>script>
 6   <script type='text/javascript'>
 7     var showhello = function(data){
 8         dwr.util.setvalue('result',dwr.util.todescriptivestring(data,1));   
 9     }
10     var getsystemdate = function(data){
11         dwr.util.setvalue('systime',dwr.util.todescriptivestring(data,2));   
12     }
13   script>
14   <style type='text/css'>
15     input.button { border: 1px outset; margin: 0px; padding: 0px; }
16     span { background: #ffffdd; white-space: pre; padding-left:20px;}
17   style>
18 head>
19 <body onload='dwr.util.useloadingmessage()'>
20     <p>
21     <h2>guice and dwrh2>
22         <input class='button' type='button' value="call helloworld 'sayhello' service" onclick="helloworld.sayhello(showhello)" />
23         <span id='result' >span>
24     p>
25     <p>
26         <input class='button' type='button' value="call helloworld 'getsystemdate' service" onclick="helloworld.getsystemdate(getsystemdate)" />
27         <span id='systime' >span>
28     p>
29 body>
30 html>

 

我们通过两个按钮来获取我们的远程调用的结果。

我对dwr的认识也仅限于此就不献丑了。有兴趣的可以研究。

4.2 整合spring

仍然使用我们的helloworld服务。


1 public interface helloworld {
2 
3     string sayhello(string user);
4 }
5 

1 public class helloworldimpl implements helloworld {
2 
3     @override
4     public string sayhello(string user) {
5         return string.format("welcome to guice with spring, %1$s. now is %2$tf %2$th:%2$tm:%2$ts.", user,new date());
6     }
7 }
8 

当然了,我们定义一个简单的spring配置文件,只有一个bean。

1 xml version="1.0" encoding="utf-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3     xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
4     xsi:schemalocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
6     <bean id="helloworld" class="cn.imxylz.study.guice.spring.helloworldimpl"
7         scope="singleton" />
8 beans>

 

然后看我们的demo程序。


 1 public static void main(string[] args) {
 2 
 3     final applicationcontext context = new classpathxmlapplicationcontext("/applicationcontext.xml", guicespringdemo.class);
 4     injector injector = guice.createinjector(new abstractmodule() {
 5         protected void configure() {
 6           bind(beanfactory.class).toinstance(context);
 7           bind(helloworld.class).toprovider(springintegration.fromspring(helloworld.class"helloworld"));
 8         }
 9       });
10     helloworld hw1 =injector.getinstance(helloworld.class);
11     string msg=hw1.sayhello("xylz");
12     system.out.println(msg);
13     helloworld hw2 =(helloworld)context.getbean("helloworld");
14     string msg2=hw2.sayhello("xylz");
15     system.out.println(msg2);
16     system.out.println(hw1==hw2);
17 }
18 

最后我们通过injector和applicationcontext都能够得到凯发k8网页登录的服务,并且凯发k8网页登录的服务hw1==hw2。

如果闲一个个服务的注入麻烦,这里还有一个简便的方法,一次将spring中的所有服务都注入。

final applicationcontext context = new classpathxmlapplicationcontext("/applicationcontext.xml", guicespringdemo.class);
        injector injector 
= guice.createinjector(new module() {
            @override
            
public void configure(binder binder) {
                springintegration.bindall(binder, context);
            }
        });

 

但是guice获取服务的方式就不一样了。

string msg=injector.getinstance(key.get(helloworldimpl.class, names.named("helloworld"))).sayhello("xylz");
system.out.println(msg);

这里我们不能getinstance(helloworld.class)来获取一个服务了,为什么呢?因为注入所有服务的时候,guice并不能知道凯发k8网页登录的服务是什么类型,于是将当作实际的类型注入了,另外由于spring允许一种类型的多个服务(bean)存在,所以自动注入的时候为了区分就需要带一个命名的注解,比如我们的helloworld,这个名称就是spring中的id。在injector中为了获取一个带注解的类型服务,我们需要com.google.inject.key对象,此对象可以讲类型和注解关联起来,这样我们就能从guice容器中获取一个服务了。

那如果我们想屏蔽真实的服务代码,也就是我们只是想客户端拿到helloworld服务而不是helloworldimpl实现怎么做?

目前只能在spring中使用代理服务。

 1 xml version="1.0" encoding="utf-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
 4     xsi:schemalocation="http://www.springframework.org/schema/beans
 5 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 6     <bean id="helloworldtarget" class="cn.imxylz.study.guice.spring.helloworldimpl"
 7         scope="singleton" />
 8     <bean id="helloworld" class="org.springframework.aop.framework.proxyfactorybean">
 9         <property name="proxyinterfaces" value="cn.imxylz.study.guice.spring.helloworld" />
10         <property name="target" ref="helloworldtarget" />
11     bean>
12 beans>

然后我们在guice中这样获取服务:

string msg=injector.getinstance(key.get(helloworld.class, names.named("helloworld"))).sayhello("xylz");
system.out.println(msg);

显然,如果客户端知道服务的实际类型并且知道spring中的id,那么仍然可以调用凯发k8网页登录的服务,比如下面的例子:

string msg3=injector.getinstance(key.get(helloworldimpl.class, names.named("helloworldtarget"))).sayhello("xylz");
system.out.println(msg3);

 

上一篇:

下一篇:



©2009-2014 imxylz
|求贤若渴
posted on 2009-12-29 00:11 imxylz 阅读(27244) 评论(5)     所属分类: j2eegoogle guice
# guice与spring整合的问题 2011-01-25 10:07
你好,我有一个guice与spring整合的问题想请教。
我有一个blogdao数据访问接口,一个blogservice业务逻辑接口。
blogdao的实现类为blogdaoimpl,而blogservice的实现类为blogserviceimpl。
然后进行如下绑定:

public class blogmodule extends abstractmodule {
protected void configure() {
applicationcontext beanfactory = new classpathxmlapplicationcontext("beans.xml");

bind(beanfactory.class).toinstance(beanfactory);
bind(blogdao.class).toprovider(fromspring(blogdao.class, "blogdaoimpl"));
bind(blogservice.class).toprovider(fromspring(blogservice.class, "blogserviceimpl"));
}
}

测试类如下:
@runwith(atunit.class)
@container(container.option.guice)
@mockframework(mockframework.option.jmock)
public class testitest implements module {
@inject
blogservice blogservice;
@inject
blogdao blogdao;

@test
public void test() {
system.out.println(blogservice);
system.out.println(blogdao);
}
}
这样可以正确打印得到对象。
然后在blogserviceimpl里面定义blogdao接口:如下:
@service
public class blogserviceimpl implements blogservice {
@inject
private blogdao blogdao;
public bloginfo getblog(int id) {
return blogdao.getblog(id);
}
}
然后在测试类里调用:
@test
public void test() {
system.out.println(blogservice.getblog(5));
}
得到了空指针的错误:java.lang.nullpointerexception
也就是说blogserviceimpl的blogdao 接口为空。
这个是什么原因造成的呢?  回复  
  

# re: google guice 入门教程07 - 整合第三方组件(1) 2011-01-26 10:18 xylz
@lxy

之所以blogdao为空是因为blogserviceimpl是由spring container托管的,而spring不支持guice的inject注入,因此对于spring bean来说,目前还不支持inject注入guice 的bean。

话说回来,你的blogserviceimpl不也是spring托管的么?既然这样,你将blogserviceimpl中的@inject private blogdao blogdao;换成@autowired private blogdao blogdao;就可以解决此问题了。  回复  
  

# re: google guice 入门教程07 - 整合第三方组件(1) 2011-01-27 09:51
我是新手,有点明白了。

不是guice管理的对象,不能由guice完成注入,应该是这样理解吧?

你的教程很好啊,比guice的文档要好多了,继续关注。

以后会出guice和mybatis的整合教程么?官方就得一个英文文档,百度也没有详细资料,我虽然已经整合了,但是有些地方不懂。  回复  
  

# re: google guice 入门教程07 - 整合第三方组件(1) 2011-01-27 11:59 xylz
@lxy
理解正确!

guice这东西自己玩玩可以,目前使用的公司还是比较少。至于与ibatis的整合目前没有计划,guice版本更新我倒是可以关注下。  回复  
  

# re: google guice 入门教程07 - 整合第三方组件(1) 2014-04-13 14:32
asas  回复  
  


©2009-2014
网站地图