Guice笔记_补充_iteye_887的博客-程序员宅基地

技术标签: java  runtime  

<p><strong>1、关于标注绑定,如若不是属性,是方法上的注入,如下适用标注</strong></p>
<p></p>
<p><textarea cols="50" rows="6" name="code" class="java">@Inject
@Www
public Service service;
//方法上的如下
@Inject
void injectService(@Www Service service) {
...
}</textarea></p>
<p></p>
<p></p>
<p><strong>2、隐式绑定</strong>,如果缺少显示绑定(即没有写任何binder),Guice会试图注入并创建一个所依赖的类的新实例,如果依赖于一个接口,Guice会寻找指向具体实现的@ImplementedBy标注,如果是依赖的是一个类,那就实例化此类。</p>
<p><textarea cols="50" rows="10" name="code" class="java">bind(ServiceImpl.class);
//自己绑定自己,当然这语句可有可无,对下面毫无影响
...
class Demo{
@Inject
Demo(ServiceImpl service){
...
}
}</textarea></p>
<p></p>
<p><strong>3、定制Provide。</strong></p>
<p></p>
<p>有时候需要手工创建自己的对象,而不是让Guice创建他们,比如,一个来自第三方的实现类需要注入,但我们不能修改源码,不能添加@Inject标注,在这里就需要 自己定制Provider,手工创建对象。</p>
<p><textarea cols="66" rows="15" name="code" class="java">class WidgetProvider implements Provider<Widget> {

final Service service;

@Inject//这里注入了第三方实现类需要的参数
WidgetProvider(Service service) {
this.service = service;
}

public Widget get() {
return new Widget(service);//这里自己手工传入参数,实例化
}
}

</textarea></p>
<p></p>
<p>例子:与JNDI集成,我们需要绑定从JNDI得到的对象。</p>
<p><textarea cols="66" rows="15" name="code" class="java">class JndiProvider<T> implements Provider<T> {

@Inject Context context;
final String name;
final Class<T> type;

JndiProvider(Class<T> type, String name) {
this.name = name;
this.type = type;
}

public T get() {
try {
return type.cast(context.lookup(name));
}
catch (NamingException e) {
throw new RuntimeException(e);
}
}

/**
* Creates a JNDI provider for the given
* type and name.
*/
static <T> Provider<T> fromJndi(
Class<T> type, String name) {
return new JndiProvider<T>(type, name);
}
}
</textarea></p>
<p></p>
<p>我们可以使用定制的JndiProvider来将DataSource绑定到来自JNDI的一个对象上。</p>
<p><textarea cols="66" rows="7" name="code" class="java">// Bind Context to the default InitialContext.
bind(Context.class).to(InitialContext.class);

// Bind to DataSource from JNDI.
bind(DataSource.class)
.toProvider(JndiProvider.fromJndi(DataSource.class, "..."));

</textarea></p>
<p></p>
<p></p>
<p><strong>4、绑定的作用域</strong></p>
<p></p>
<p>缺省情况下,Guice为每次注入创建一个新的对象,即“无作用域”</p>
<p>可以在配置绑定时指明作用域</p>
<p><textarea cols="68" rows="7" name="code" class="java">bind(MySingleton.class).in(Scopes.SINGLETON);
//或用标注,Guice缺省支持@Singleton;
@Singleton
class MySingleton {
...
}
//用in()的优先级高于标注

//可以使用Binder.bindScope()为定制的作用域 指定 标注.
//如,对于标注@SessionScoped 和 一个Scope的实现ServletScopes.SESSION;
binder.bindScope(SessionScoped.class,ServletScopes.SESSION);
</textarea></p>
<p></p>
<p></p>
<p><strong>创建作用域标注</strong></p>
<p></p>
<p>标注必须:</p>
<li>有一个 <span style="font-family: Courier New;">@Retention(RUNTIME)</span> 标注,从而使我们可以在运行时看到该标注。 </li>
<li>有一个 <span style="font-family: Courier New;">@Target({TYPE})</span> 标注。作用域标注只用于实现类。 </li>
<li>有一个 <span style="font-family: Courier New;">@ScopeAnnotation</span> 元标注。一个类只能使用一个此类标注。 </li>
<p><textarea cols="50" rows="8" name="code" class="java">/**
* Scopes bindings to the current transaction.
*/
@Retention(RUNTIME)
@Target({TYPE})
@ScopeAnnotation
public @interface TransactionScoped {} </textarea></p>
<p></p>
<p></p>
<p><strong>5、尽早加载绑定(类似Spring的layzload=false)</strong></p>
<p></p>
<p>有时你希望在启动时加载一个对象,可以通过以下方法实现初始化逻辑,通过在Guice必须首先初始化的单件对象上创造依赖关系来控制初始化顺序。</p>
<p><textarea cols="50" rows="15" name="code" class="java">bind(StartupTask.class).asEagerSingleton();

</textarea></p>
<p></p>
<p></p>
<p><strong>6、在不同作用域间注入</strong></p>
<ul>
<li>大作用域对象 ->(注入) 小作用域对象或相同作用域的对象中 是安全的。</li>
<li>小作用域对象 ->(注入) 大作用域对象时可能会出错,这时应该注入一个Provider<T>在需要时从较小的作用域中获取对象,并确保在T的作用域之外,永远不要调用这个提供者。</li>
</ul>
<p></p>
<p></p>
<p><strong>7、开发阶段</strong></p>
<p></p>
<p>Guice 明白你的应用开发需要经历不同的阶段。你可以在创建容器时告诉它应用程序运行在哪一个阶段。Guice 目前支持“开发”和“产品”两个阶段。我们发现测试通常属于其中某一个阶段。</p>
<ul>
<li>在开发阶段,Guice 会<span style="">根据</span>需要加载单件对象。这样,你的应用<span style="">程序</span>可以快速启动,只加载你正在测试的部分。</li>
<li>在产品阶段,Guice 会在启动时加载全部单件对象。这帮助你尽早捕获错误,提前优化性能。</li>
</ul>
<p></p>
<p><strong>8、拦截方法</strong></p>
<p><strong></strong></p>
<p>Guice 使用 <a title="AOP Alliance API" href="http://aopalliance.sourceforge.net/">AOP Alliance API</a>支持简单的方法拦截。可以在模块中使用 <span style="font-family: Courier New;">Binder 绑定拦截器。例如,</span>对标注有 <span style="font-family: Courier New;">@Transactional 的方法</span><span style="">应</span><span style="font-family: Courier New;">用</span><span style="">事务</span><span style="font-family: Courier New;">拦截器:</span></p>
<p><span style="font-family: Courier New;"><textarea cols="62" rows="15" name="code" class="java">import static com.google.inject.matcher.Matchers.*;

...

binder.bindInterceptor(
any(), // Match classes.
annotatedWith(Transactional.class), // Match methods.
new TransactionInterceptor() // The interceptor.
);

</textarea></span></p>
<p><span style="font-family: Courier New;">尽量让匹配代码多做些过滤工作,而不是在拦截器中过滤。因为匹配代码只在启动时运行一次。 </span>
</p>
<p><strong>10、Struts2支持</strong></p>
<p></p>
<p>要在 Struts 2.0.6 或更高版本中安装 Guice Struts 2插件,只要将 <span style="font-family: Courier New;">guice-struts2-plugin-1.0.jar</span> 包含在你的 Web 应用的classpath 中,并在 <span style="font-family: Courier New;">struts.xml </span><span style="">文件</span><span style="font-family: Courier New;">中</span>选择 Guice 作为你的 <span style="font-family: Courier New;">ObjectFactory</span> 实现即可:<br><br><span style="font-family: Courier New;"> <constant name="struts.objectFactory" value="guice" /></span> </p>
<p></p>
<p>Guice 会注入所有你的 Struts 2 对象,包括动作和拦截器。你甚至可以设置动作类的作用域。你也可以在你的 <span style="font-family: Courier New;">struts.xml</span> 文件中指定 Guice 的<span style="font-family: Courier New;">Module</span>: </p>
<p></p>
<p><span style="font-family: Courier New;"> <constant name="guice.module" value="mypackage.MyModule"/></span></p>
<p><span style="font-family: Courier New;"><br></span>如果你的所有绑定都是隐式的,你就根本不用定义模块了。</p>
<p><br></p>

<p></p>
<p></p>
<p><strong>9、可选注入</strong></p>
<p></p>
<p>有时你的代码应该在无论绑定是否存在的时候都能工作。在这些情况下,你可以使用 <span style="font-family: Courier New;">@Inject(optional=true)</span>,Guice 会在有绑定可用时,用一个绑定实现覆盖你的缺省实现。例如:<br><br><textarea cols="70" rows="1" name="code" class="java">@Inject(optional=true) Formatter formatter = new DefaultFormatter();</textarea><br>如果谁为 <span style="font-family: Courier New;">Formatter </span>创建了一个绑定,Guice 会基于该绑定注入实例。否则,如果 <span style="font-family: Courier New;">Formatter</span> 不能被注入(参见<em>隐式绑定</em>),Guice 会忽略可选成员。<br><br>可选注入只能应用于字段和方法,而不能用于构造<span style="">函数</span>。对于方法,如果一个参数的绑定找不到,Guice 就不会注入该方法,即便其他参数的绑定是可用的。</p>
<p></p>
<p><br></p>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/iteye_887/article/details/81887943

智能推荐

【小5聊】jQuery基础之触发a标签的click事件无效的解决方法_全栈小5的博客-程序员宅基地

使用trigger触发click事件有时在特定情况下无效,需要使用click方式直接替换1、代码注入方式无效在浏览器代码注入,trigger触发click无效,但在console输出区域又可以代码如下$(".a").trigger('click'); //一般此类方式都可以触发2、解决方法代码$(".a")[0].click();...

分布式软件体系结构风格(C/S,B/S)-程序员宅基地

分布式软件体系结构风格1、 三层C/S结构2、 三层B/S结构 了解更多软件体系结构三层C/S结构(3-Tier C/S Architecture)§第1层:用户界面GUI—表示层——客户机§第2层:业务逻辑—功能层——应用服务器§第3层:数据库—数据层——数据库服务器基本组件:–数据库服务器• 存放数据的数据库、负责数据处理的业务逻辑;–_分布式软件体系结构

定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。_定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问-程序员宅基地

#include<stdio.h>#include<math.h>#include<string.h>#include<stdlib.h>struct { int year; int month; int day;}data;int main() { int days; printf("请输入年、月、日:"); scanf_s("%d,%d,%d", &data.year, &da..._定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问

Denoise auto-encoder的一个理解-程序员宅基地

这几天反复的看denoise auto-encoder的解释,尤其是

Java程序员必备基础:Java代码是怎么运行的?-程序员宅基地

前言作为一名Java程序员,我们需要知道Java代码是怎么运行的。最近复习了深入理解Java虚拟机,做了一下总结,希望对大家有帮助,如果有不正确的地方,..._怎么看java代码运行时间

Nearth===022/c#异常处理(练习1---对异常正确输出的理解)_c#实现一个计算器,出上述异常,然后捕获异常,在输出框在中显示异常。如果符合要求,-程序员宅基地

读代码,运行代码,学会理解异常代码的正确输出------>运行结果:学习代码:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ExceptionDemo{ public class MyException : Appli..._c#实现一个计算器,出上述异常,然后捕获异常,在输出框在中显示异常。如果符合要求,

随便推点

ElasticSearch用head批量删除多个索引文件_es head-plugin 批量删除-程序员宅基地

POST my_index/_delete_by_query{ "query":{ "term":{ "datetime":1578974467012 } }}添加筛选条件,删除符合条件的数据_es head-plugin 批量删除

Git入门到高级系列2-git高级操作-程序员宅基地

视频课程地址腾讯课堂git 清理git clean命令用来从你的工作目录中删除所有没有tracked过的文件。命令说明git clean -n告诉你哪些文件会被删除. 记住他不会真正的删除文件, 只是一个提醒。git clean -d删除未跟踪的目录git clean -f删除当前目录下所有没有track过的文件...

【正完成】网络模型-程序员宅基地

网络模型分几层?http,ip,tcp分别属于哪一层?介绍一下HTTP协议。

win应用只允许单个实例运行,并将已运行实例窗口置顶-程序员宅基地

关键词:windows,c++,桌面应用,单个实例,窗口置顶目标:1.判断本程序是否已有一个实例在运行。2.若有,则激活已在运行的实例(将其窗口置顶),并退出当前运行。 1.使用semaphore来检测是否已有实例在运行(也可以用mutex,文件等其他方式)HANDLE g_hSingleSema = ::CreateSemaphore(NULL, 1, 1, _T("sing

“无法启动调试 没有正确安装调试器 请运行安装程序安装或修复调试器”-程序员宅基地

“无法启动调试 没有正确安装调试器 请运行安装程序安装或修复调试器”我记得以前为提升电脑速度进行优化的时候,将Machine Debug Manager服务给关闭了,想着去将该服务打开就可以了。当打开Windows计算机服务查看器以后,发现里面没有这个服务(服务查看器可以通过下面步骤打开:点击桌面左下角“开始”,选择“运行”,输入“services.msc”,回车)。没有M

Access violation at address 77106D4E in module 'ntdll.dll'. Write of address 004051A5.-程序员宅基地

Access violation at address 77106D4E in module 'ntdll.dll'. Write of address 004051A5.开发的程序,放到其他电脑上,打开其中3个窗口的时候弹出这个提示,打开其他窗口没问题,怎么回事?可能是项目较大,我的这个项目最后达到50多M,我把一些没用的文件删除,变成40多M,再编译,就没问题了。另_in module 'ntdll.dll