Google Guice 入门示例

本贴最后更新于 2693 天前,其中的信息可能已经水流花落

Google Guice是一个依赖注入(DI)框架,实现了控制反转(IOC)。


优点:比spring轻,被越来越多的开源工具使用

缺点:调用时出现异常时,Guice不会抛出异常。需要开发者自己解决。


本文用一个示例,来说明这种调用。


背景

在数据流的处理中,会用到生产者消费者模型,如通过http服务接收到日志数据,然后经过业务处理,最终存储到本地磁盘中。

随着业务变化,数据生产者会变化,如不再通过http接收数据,而是通过从消息队列中读取数据。数据消费者也会变化,如不再存储到本地磁盘,而是存储到远程的Hadoop中。

在这个过程中,业务处理逻辑是不变的,我们也希望能够复用业务代码逻辑,同时可以选用合适的生产和消费实现。


传统实现

那么怎么做呢?一般会写三个接口文件:生产者,消费者,业务处理者,如下:


// 业务处理接口


public interface GatewayService {
void start();

void stop();

}

// 生产者接口
public interface ProduceService {

	List<String> getDataList();

	void start();

	void stop();
}



// 消费者接口
public interface ConsumeService {
void consume(List&lt;String&gt; dataList);

}


然后分别实现:


// 业务处理实现类
public class GatewayServiceImpl implements GatewayService {

	private ConsumeService consumer;

	private ProduceService producer;

	private volatile boolean isRunning = false;

	public GatewayServiceImpl(ProduceService producer, ConsumeService consumer) {
		this.producer = producer;
		this.consumer = consumer;
	}

	public void start() {
		if (isRunning) {
			throw new IllegalStateException("already running");
		}

		new Thread(new Runnable() {
			public void run() {
				try {
					isRunning = true;
					while (isRunning) {
						List<String> dataList = producer.getDataList();
						consumer.consume(dataList);
					}
				} finally {
					isRunning = false;
				}
			}
		}, "gateway-service").start();
	}

	public void stop() {
		this.isRunning = false;
	}
}

// 生产者基类



public abstract class AbstractProducerService implements ProduceService {
public void start() {
}

public void stop() {
}

}



// 生产类实现类
public class MockProducer extends AbstractProducerService implements ProduceService {
private static AtomicLong counter = new AtomicLong(0);

public List&lt;String&gt; getDataList() {
	try {
		Thread.sleep(500L);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	return Collections.singletonList(String.valueOf(counter.incrementAndGet()));
}

}

// 消费者实现类
public class MockConsumer implements ConsumeService {

	public void consume(List<String> dataList) {
		System.out.println("MockConsumer: " + dataList);
	}
}


最后把代码组装起来


	public static void main(String[] args) throws InterruptedException {
		ProduceService producer = new MockProducer();
		ConsumeService consumer = new MockConsumer();
		GatewayService service = new GatewayServiceImpl(producer, consumer);
		service.start();
		Thread.sleep(10000L);
		service.stop();
	}



这是一般的写法


Guice实现

如果采用Guice的话,将new 新的实例的过程,由guice来接管。



public class MockGatewayModule implements Module {
public void configure(Binder binder) {
	binder.bind(ConsumeService.class).to(MockConsumer.class);
	binder.bind(ProduceService.class).to(MockProducer.class);
	binder.bind(GatewayService.class).to(GatewayServiceImpl.class).asEagerSingleton();
}

}


然后将GatewayService接口的初始化中参数的传入,由注入来实现,下面的代码中,增加了一个 @Inject注解


public class GatewayServiceImpl implements GatewayService {
private ConsumeService consumer;

private ProduceService producer;

private volatile boolean isRunning = false;

@Inject
public GatewayServiceImpl(ProduceService producer, ConsumeService consumer) {
	this.producer = producer;
	this.consumer = consumer;
}

public void start() {
	if (isRunning) {
		throw new IllegalStateException("already running");
	}

	new Thread(new Runnable() {
		public void run() {
			try {
				isRunning = true;
				while (isRunning) {
					List&lt;String&gt; dataList = producer.getDataList();
					consumer.consume(dataList);
				}
			} finally {
				isRunning = false;
			}
		}
	}, "gateway-service").start();
}

public void stop() {
	this.isRunning = false;
}

}




最近新的代码组装方式:


	public static void main(String[] args) throws InterruptedException {
		Injector injector = Guice.createInjector(new MockGatewayModule());
		injector.getInstance(GatewayService.class).start();
		Thread.sleep(10000L);
		injector.getInstance(GatewayService.class).stop();
	}

结果

执行效果是相同的,但是有下面的两个特点:


  1. 接口实例的产生放在了Module中来进行,省去了new的过程
  2. 通过注入,避免了实例中参数的显式传入



进一步阅读:







  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...