由于Spring太过庞大,所以本人也一直都不太喜欢,当guice1出来时,就关注过一阵子,但始终没有行动去试用,听说2.0出来了,最近闲着也没事,就去试用了一下,单从IOC方面来说,做得的确比较出色。
于是做了一个例子,把常用的功能都试了一下,其中需要的JAR包只有两个:
aopalliance.jar
guice-2.0.jar
下面是例子的代码:
public interface Service {
public void sayHello();
}
public class ServiceImp implements Service {
public void sayHello() {
System.out.println("ServiceImp say Hello !");
}
}
然后需要一个Model建立接口与类之间的映射关系,
由于包含的功能比较多,所以代码相对有一点复杂,不过这个类是最重要的
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Provides;
import com.google.inject.name.Names;
import demo.HeroModule;
public class ServiceModel extends AbstractModule {
@Override
protected void configure() {
// 与在Service接口上声明@ImplementedBy(ServiceImp.class)等价
// 手工实例化想绑定的对象
// this.bind(Service.class).toInstance(new ServiceImp());
// this.bind(Service.class).to(ServiceImp.class);
// When your @Provides methods start to grow complex, you may consider
// moving them to a class of their own
this.bind(Service.class).toProvider(ServiceProvider.class);
// this.bind(String.class).annotatedWith(Names.named("username")).toInstance("qiuqiu");
this.bindConstant().annotatedWith(Names.named("username")).to("qiuqiu");
loadProperties();
}
/*
* When you need code to create an object, use an @Provides method. The
* method must be defined within a module, and it must have an @Provides
* annotation. The method's return type is the bound type. Whenever the
* injector needs an instance of that type, it will invoke the method.
*/
@Provides
public User provide() {
System.out.println("++++++++=============");
User user = new User();
user.setUsername("myprovide");
return user;
}
private void loadProperties() {
InputStream stream = this.getClass().getResourceAsStream(
"/app.properties");
Properties appProperties = new Properties();
try {
appProperties.load(stream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Names.bindProperties(this.binder(), appProperties);
}
}
Provider在管理手工创建对象时会比@Provides灵活一些:
import com.google.inject.Provider;
public class ServiceProvider implements Provider<Service> {
@Override
public Service get() {
System.out.println("ServiceProvider==-=-=-=-=_+_+_+_+_+_+_+_+");
// TODO Auto-generated method stub
Service service = new ServiceImp();
return service;
}
}
还有一辅助类:
public class User{
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
还有一属性文件app.properties,很简单:
db.user=mysql
db.pwd=2009
经过上面一系列的准备,就可以进行测试了了:
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
public class Client {
private Service service;
private User user;
private String username;
private String db_user;
private String db_pwd;
@Inject
public void setDB(@Named("db.user") String db_user,
@Named("db.pwd") String db_pwd) {
this.db_user = db_user;
this.db_pwd = db_pwd;
}
@Inject
public void setUsername(@Named("username") String username) {
this.username = username;
}
@Inject
public void setUser(User user) {
this.user = user;
}
@Inject
public void setService(Service service) {
this.service = service;
}
@Test
public void testGuice() {
Injector injector = Guice.createInjector(new ServiceModel());
// 如果不用@Inject注入,则用这种方法
// Service service = injector.getInstance(ServiceImp.class);
injector.injectMembers(this);
service.sayHello();
}
@Test
public void testBindConstant() {
System.out.println("username=" + username);
}
@Test
public void testBindProvides() {
Injector injector = Guice.createInjector(new ServiceModel());
injector.injectMembers(this);
// 必须要调用上面的注入方法
Assert.assertEquals(user.getUsername(), "myprovide");
}
@Test
public void testProperties() {
Injector injector = Guice.createInjector(new ServiceModel());
injector.injectMembers(this);
Assert.assertEquals(db_user, "mysql");
Assert.assertEquals(db_pwd, "2009");
}
}
大体过程就这样,还有一些细小的功能没有仔细去体会,以后有时间再来完善吧!