Google Guice学习一(基础)

Google Guice是依赖注解的DI容器,支持字段、方法和构造函数的注入依赖。

使用方法步骤为配置需要注入的字段、配置模板、使用Injector API获得实例。

 

 一、 支持的注入方式

1、字段注入

最常见的方式,使用@Inject注解完成

@Inject

private XmlUserLoader loader;

 

2、构造函数注入

@Inject

public XmlUserServiceImpl(XmlUserLoader loader)

{

this.loader=loader;

}

  3、setter方法注入

@Inject

public void setLoader(XmlUserLoader loader)

{

this.loader = loader;

}

  二、 注入的API(配置模板)

Guice通过配置Module的方式来绑定关系。

public class ClientModule implements Module
{

	public void configure(Binder binder)
	{
		binder.bind(UserService.class).to(XmlUserServiceImpl.class);
	}

}
 
Binder中提供了很多绑定的API,这些API其实可以理解为配置文件。支持很多种类型的绑定 1、绑定一个具体的子类:
binder.bind(UserService.class).to(XmlUserServiceImpl.class);

2、绑定一个实例:

binder.bind(UserService.class).toInstance(new XmlUserServiceImpl());

3、支持注解形式的绑定:

binder.bind(String.class).annotatedWith(Names.named("xmlUrl")).toInstance("/user.xml");

这样如果存在如下代码:

        @Inject

@Named("xmlUrl")

private String xmlUrl;

那么这个字符串将会设置为"/user.xml"

当然也可以设置自定义的注解。但是个人认为Names这个注解已经基本满足要求了。

可以看一下com.google.inject.name.Names.named(String)方法,其实返回的是个注解,类继承了注解。

class NamedImpl implements com.google.inject.name.Named, Serializable {

  private final String value;
           //com.google.inject.name.Named是个注解类型
  public NamedImpl(String value) {
    this.value = checkNotNull(value, "name");
  }

自定义注解的示例:

@Retention(RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@BindingAnnotation      //这个必须要加上才行,否则报错
public @interface English
{

}

 那么在Module中的使用如下:

public class Client
{
	@Inject
	@English
	private MyService service;

	public void greeting()
	{
		System.out.println(service.greeting());
	}

	public static void main(String[] args)
	{
		Module module = new Module()
		{
			public void configure(Binder binder)
			{
				binder.bind(MyService.class).annotatedWith(English.class).to(EnglishService.class);
			}
		};
		Injector i = Guice.createInjector(module);
		Client client = i.getInstance(Client.class);
		client.greeting();
	}
}

 4、provider形式的绑定

provider提供了更灵活的形式可以自定义创建对象的逻辑。框架提供了两种provider的形式。

A、实现provider接口,并绑定

修改上面示例如下:

final Provider<MyService> provider = new Provider<MyService>()
		{

			public MyService get()
			{
				// 用户的自定义创建逻辑
				return new EnglishService();
			}
		};

		Module module = new Module()
		{
			public void configure(Binder binder)
			{
				binder.bind(MyService.class).annotatedWith(English.class).toProvider(provider);
			}
		};

B、通过@Provides在Module中定义方法

	@Provides
        @Name("test")
	public MyService getMyService()
	{
		// 用户的自定义创建逻辑
		return new EnglishService();
	}

 5、静态类注入

对静态字段类注入:

	public void configure(Binder binder)
	{
		binder.bindConstant().annotatedWith(Names.named(("DataTimeUtils"))).to("yyyy-MM-dd");
		binder.requestStaticInjection(DataTimeUtils.class);
	}


@Inject
	@Named("DataTimeUtils")
	private static String dataFormat;

 6、不明确的注入:

通过ImplementedBy注解指定需要使用的类

@ImplementedBy(EnglishService.class)

public interface MyService

{

String greeting();

}

三、 使用Injector API获取实例

	Injector i = Guice.createInjector(new MyModule());
		Client client = i.getInstance(Client.class);   //直接获取实例
		client.greeting();

 

Client client = new Client();
		Injector i = Guice.createInjector(new MyModule());
		i.injectMembers(client);   //调用该API,填充字段
		client.greeting();

 

binder.bind(UserService.class).to(XmlUserServiceImpl.class);

猜你喜欢

转载自fengozl.iteye.com/blog/2357935