博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
慕课网_《使用Google Guice实现依赖注入》学习总结
阅读量:7125 次
发布时间:2019-06-28

本文共 17222 字,大约阅读时间需要 57 分钟。

时间:2017年10月14日星期六

说明:本文部分内容均来自慕课网。@慕课网:
教学源码:
学习源码:

第一章:课程介绍

1-1 课程简介

Google Guice:Guice是啥

Guice读音:juiceGuice is a lightweight dependency injection framework for javaGuice 是轻量级的依赖注入框架

Google Guice:说明

Java:一个java的框架、需要有java基础dependency injection:什么是dependency、剥离dependency、注入dependencylightweight:轻量级(代码少、易维护、性能优异),跟Spring比较。但是:学习曲线陡峭、对开发者的要求太高了

课程目标

理解、重新理解dependency injection掌握Guice的语法,更要掌握Guice的设计理念开始在你的下一个项目中使用Guice

课程要点

什么是Guicedependency injection:改造Hello World程序注入(Injection)绑定(Binding)作用域或生命周期(Scope)Guice AOP使用Guice和SpringBoot协作搭建一个简单的Web应用Guice vs Spring

1-2 产生原因

Spring的不足

手动配置:使用xml进行配置,配置太过庞大自动配置:Spring提供了自动配置,复杂项目无法实现

Guice不同于Spring

取消xml取消bean的概念使用Constructor来注入泛型支持一个专注于Dependency Injection的框架

参考资料

https://github.com/google/guice/wiki/Motivationhttps://github.com/google/guice/wiki/ExternalDocumentation更多利用英文资料,如Stackoverflow

第二章:理解依赖

2-1 基础配置

Hello Guice

配置Guice环境Dependency Injection基础改造Hello World

创建名为guicedemo的maven工程pom如下

4.0.0
com.myimooc
guicedemo
0.0.1-SNAPSHOT
jar
guicedemo
http://maven.apache.org
UTF-8
1.8
1.8
1.8
com.google.inject
guice
4.1.0
com.google.inject.extensions
guice-multibindings
4.1.0
junit
junit
4.12
test

2-2 依赖分析

经典Hello World分析

clipboard.png

核心算法:将指定内容输出至指定目标

改造Hello World程序

面向对象化消除Dependency用Guice来配置Dependency

2-3 面向对象

代码编写

1.编写MyApplet类

package com.myimooc.guicedemo;/** * @title Applet类 * @describe 提供run()方法 * @author zc * @version 1.0 2017-10-15 */public interface MyApplet extends Runnable{    }

2.编写HelloWorldPrinter类

package com.myimooc.guicedemo.helloworlddemo;import com.myimooc.guicedemo.MyApplet;/** * @title HelloWorldPrinter类 * @describe 提供打印HelloWorld的功能 * @author zc * @version 1.0 2017-10-15 */public class HelloWorldPrinter implements MyApplet {        private void printHelloWorld() {        System.out.println("Hello World!");    }        @Override    public void run() {        printHelloWorld();    }}

3.编写Configuration类

package com.myimooc.guicedemo;import com.myimooc.guicedemo.helloworlddemo.HelloWorldPrinter;/** * @title Configuration类 * @describe 程序启动配置类 * @author zc * @version 1.0 2017-10-15 */public class Configuration {        public static MyApplet getMainApplet() {        return new HelloWorldPrinter();    }    }

4.编写App类

package com.myimooc.guicedemo;/** * @title 启动类 * @describe 改造HelloWorld类 * @author zc * @version 1.0 2017-10-15 */public class App {    /**     * main方法的作用     * bootstrap:     *   parse command line:解析命令行参数     *   set up environment:配置环境参数     *   kick off main logic:启动程序逻辑     * @param args     */    public static void main(String[] args) {        MyApplet mainApplet = Configuration.getMainApplet();        mainApplet.run();    }}

面向对象化小结

善于运用IDE提供的重构能力    Ctrl + 1:猜测下一步动作    Ctrl + shift + r:重命名    先写代码,再让其编译通过    先思考确定需要什么,然后再机械性劳动实现函数命名    从实现角度:精确描述函数干什么    从调用者角度:描述调用者需求    两者不匹配:需要进行抽象的点

2-4 提取依赖

代码编写

1.编写MyApplet类

package com.myimooc.guicedemo.noguice;/** * @title MyApplet类 * @describe 提供run()方法 * @author zc * @version 1.0 2017-10-15 */public interface MyApplet extends Runnable{    }

2.编写StringWritingApplet类

package com.myimooc.guicedemo.noguice.helloworlddemo;import com.myimooc.guicedemo.noguice.MyApplet;/** * @title HelloWorldPrinter类 * @describe 提供打印HelloWorld的功能 * @author zc * @version 1.0 2017-10-15 */public class StringWritingApplet implements MyApplet {        private MyDestination destination;    private StringProvider stringProvider;        public StringWritingApplet(MyDestination destination,StringProvider stringProvider) {        super();        this.destination = destination;        this.stringProvider = stringProvider;    }    private void writeString() {        destination.write(stringProvider.get());    }        @Override    public void run() {        writeString();    }}

3.编写StringProvider类

package com.myimooc.guicedemo.noguice.helloworlddemo;/** * @title StringProvider类 * @describe 提供get()方法 * @author zc * @version 1.0 2017-10-15 */public interface StringProvider {    String get();}

4.编写MyDestination类

package com.myimooc.guicedemo.noguice.helloworlddemo;/** * @title MyDestination类 * @describe 提供write()方法 * @author zc * @version 1.0 2017-10-15 */public interface MyDestination {    void write(String string);}

5.编写PrintStreamWriter类

package com.myimooc.guicedemo.noguice.helloworlddemo;import java.io.PrintStream;/** * @title PrintStreamWriter类 * @describe 实现write()方法 * @author zc * @version 1.0 2017-10-15 */public class PrintStreamWriter implements MyDestination {    private PrintStream destination;        public PrintStreamWriter(PrintStream destination) {        super();        this.destination = destination;    }    @Override    public void write(String string) {        destination = System.out;        destination.println(string);    }}

6.编写Configuration类

package com.myimooc.guicedemo.noguice;import com.myimooc.guicedemo.noguice.helloworlddemo.PrintStreamWriter;import com.myimooc.guicedemo.noguice.helloworlddemo.StringProvider;import com.myimooc.guicedemo.noguice.helloworlddemo.StringWritingApplet;/** * @title Configuration类 * @describe 程序启动配置类 * @author zc * @version 1.0 2017-10-15 */public class Configuration {        public static MyApplet getMainApplet() {        return new StringWritingApplet(               new PrintStreamWriter(System.out),               new StringProvider() {                    @Override                    public String get() {                        return "Hello World";                    }                });    }}

7.编写App类

package com.myimooc.guicedemo.noguice;/** * @title 启动类 * @describe 改造HelloWorld类 * @author zc * @version 1.0 2017-10-15 */public class App {    /**     * main方法的作用     * bootstrap:     *   parse command line:解析命令行参数     *   set up environment:配置环境参数     *   kick off main logic:启动程序逻辑     * @param args     */    public static void main(String[] args) {        MyApplet mainApplet = Configuration.getMainApplet();        mainApplet.run();    }}

消除Dependency小结

clipboard.png

2-5 配置依赖

代码编写

1.编写MyApplet类

package com.myimooc.guicedemo.useguice;/** * @title MyApplet类 * @describe 提供run()方法 * @author zc * @version 1.0 2017-10-15 */public interface MyApplet extends Runnable{    }

2.编写StringWritingApplet类

package com.myimooc.guicedemo.useguice.helloworlddemo;import com.google.inject.Inject;import com.google.inject.Provider;import com.myimooc.guicedemo.useguice.MyApplet;/** * @title HelloWorldPrinter类 * @describe 提供打印HelloWorld的功能 * @author zc * @version 1.0 2017-10-15 */public class StringWritingApplet implements MyApplet {        private MyDestination destination;    private Provider
stringProvider; @Inject public StringWritingApplet(MyDestination destination,@Output Provider
stringProvider) { super(); this.destination = destination; this.stringProvider = stringProvider; } private void writeString() { destination.write(stringProvider.get()); } @Override public void run() { writeString(); }}

3.编写MyDestination类

package com.myimooc.guicedemo.useguice.helloworlddemo;/** * @title MyDestination类 * @describe 提供write()方法 * @author zc * @version 1.0 2017-10-15 */public interface MyDestination {    void write(String string);}

4.编写PrintStreamWriter类

package com.myimooc.guicedemo.useguice.helloworlddemo;import java.io.PrintStream;import javax.inject.Inject;/** * @title PrintStreamWriter类 * @describe 实现write()方法 * @author zc * @version 1.0 2017-10-15 */public class PrintStreamWriter implements MyDestination {    private PrintStream destination;        @Inject    public PrintStreamWriter(PrintStream destination) {        super();        this.destination = destination;    }    @Override    public void write(String string) {        destination = System.out;        destination.println(string);    }}

5.编写Output类

package com.myimooc.guicedemo.useguice.helloworlddemo;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import com.google.inject.BindingAnnotation;/** * @title Output注解 * @describe  * @author zc * @version 1.0 2017-10-15 */@Retention(RetentionPolicy.RUNTIME)@BindingAnnotationpublic @interface Output {}

6.编写HelloWorldModule类

package com.myimooc.guicedemo.useguice.helloworlddemo;import java.io.PrintStream;import com.google.inject.AbstractModule;import com.myimooc.guicedemo.useguice.MyApplet;/** * @title HelloWorldModule类 * @describe HelloWorld模块的依赖配置 * @author zc * @version 1.0 2017-10-15 */public class HelloWorldModule extends AbstractModule{        @Override    protected void configure() {        bind(MyApplet.class).to(StringWritingApplet.class);        bind(MyDestination.class).to(PrintStreamWriter.class);        bind(PrintStream.class).toInstance(System.out);        bind(String.class).annotatedWith(Output.class).toInstance("Hello World");    }}

7.编写MainModule类

package com.myimooc.guicedemo.useguice;import com.google.inject.AbstractModule;import com.myimooc.guicedemo.useguice.helloworlddemo.HelloWorldModule;/** * @title MainModule类 * @describe Guice用来配置的类 * @author zc * @version 1.0 2017-10-15 */public class MainModule extends AbstractModule{    @Override    protected void configure() {        install(new HelloWorldModule());    }}

8.编写App类

package com.myimooc.guicedemo.useguice;import com.google.inject.Guice;/** * @title 启动类 * @describe 改造HelloWorld类 * @author zc * @version 1.0 2017-10-15 */public class App {    /**     * main方法的作用     * bootstrap:     *   parse command line:解析命令行参数     *   set up environment:配置环境参数     *   kick off main logic:启动程序逻辑     * @param args     */    public static void main(String[] args) {        MyApplet mainApplet = Guice                .createInjector(new MainModule())                .getInstance(MyApplet.class);        mainApplet.run();    }}

Guice配置Dependency小结

clipboard.png

第三章:注入依赖

3-1 基本注入

注入图解

clipboard.png

注入(Injection)

构造函数注入    使用final来区分dependency和状态    注入时不考虑如何实现或绑定成员变量注入    用于测试    使用injectMembers来注入测试用例

代码编写

1.编写OrderService类

2.编写PaymentService类

3.编写PriceService类

4.编写OrderServiceImpl类

5.编写PaymentServiceImpl类

6.编写PriceServiceImpl类

7.编写SessionManager类

8.编写ServerModule类

9.编写OrderServiceTest类

受篇幅限制,源码请到我的github地址查看

3-2 其他注入

注入Provider

clipboard.png

如何注入Provider

DatabaseConnection dbConnProvider< DatabaseConnection > dbConnProviderGuice会考虑对象生命周期需要时可以自己实现Provider

命名注入

@Inject @Named(“dbSpec”) private String dbSpec;@Inject @LogFileName private String logFileName;使用@Named:参数来自配置文件或命令行、或者为了开发方便使用属性:通常采用此方法

代码编写

1.修改SessionManager类

package com.myimooc.guicedemo.server.impl;import javax.inject.Inject;import com.google.inject.Provider;/** * @title session管理类 * @describe 模拟订单系统 * @author zc * @version 1.0 2017-10-15 */public class SessionManager {        private final Provider
sessionIdProvider; @Inject public SessionManager(@SessionId Provider
sessionIdProvider) { super(); this.sessionIdProvider = sessionIdProvider; } public Long getSessionId() { return sessionIdProvider.get(); }}

2.修改ServerModule类

package com.myimooc.guicedemo.server.impl;import com.google.inject.AbstractModule;import com.google.inject.Provides;import com.myimooc.guicedemo.server.OrderService;import com.myimooc.guicedemo.server.PaymentService;import com.myimooc.guicedemo.server.PriceService;/** * @title ServerModule类 * @describe 绑定依赖 * @author zc * @version 1.0 2017-10-15 */public class ServerModule extends AbstractModule{    @Override    protected void configure() {        bind(OrderService.class).to(OrderServiceImpl.class);        bind(PaymentService.class).to(PaymentServiceImpl.class);        bind(PriceService.class).to(PriceServiceImpl.class);    }        @Provides     @SessionId    Long generateSessionId(){        return System.currentTimeMillis();    }}

3.编写SessionId类

package com.myimooc.guicedemo.server.impl;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import com.google.inject.BindingAnnotation;/** * @title SessionId注解 * @describe 用来绑定数据 * @author zc * @version 1.0 2017-10-15 */@Retention(RetentionPolicy.RUNTIME)@BindingAnnotationpublic @interface SessionId {}

4.编写SessionManagerTest类

package com.myimooc.guicedemo.server.impl;import static org.junit.Assert.assertNotEquals;import javax.inject.Inject;import org.junit.Before;import org.junit.Test;import com.google.inject.Guice;/** * @title 测试类 * @describe 测试@Provides * @author zc * @version 1.0 2017-10-15 */public class SessionManagerTest {        @Inject    SessionManager sessionManager;        @Before    public void setUp(){        Guice.createInjector(new ServerModule())             .injectMembers(this);    }        @Test    public void testGetSessionId() throws InterruptedException{        Long sessionId1 = sessionManager.getSessionId();        Thread.sleep(1000);        Long sessionId2 = sessionManager.getSessionId();        assertNotEquals(sessionId1.longValue(), sessionId2.longValue());    }    }

第四章:绑定依赖

4-1 绑定详解

绑定图解

clipboard.png

绑定

类名绑定实例绑定连接绑定Provider绑定命名绑定泛型绑定集合绑定

4-2 模块组织

Module的相互关系

并列:Guice.createInjector(module1,module2,…)嵌套:install(module)覆盖:Modules.override(module1).with(module2)

Module何时被运行

Module里存放了很多表达式Module不被“运行”Guice.createInjector()时记录所有表达式

系统何时初始化

没有“初始化”概念,没有Spring的Configuration Timeinjector.getInstance()时根据表达式调用构造函数

4-3 绑定示例

案例:HelloWorld与命令行

让HelloWorld打印命令行参数让HelloWorld通过命令行决定启动哪个Applet

代码编写

1.编写MyApplet类

2.编写Applets类

3.编写StringWritingApplet类

4.编写PrintLineApplet类

5.编写MyDestination类

6.编写PrintStreamWriter类

7.编写Output类

8.编写Args类

9.编写HelloWorldModule类

10.编写PrintLineModule类

11.编写CommandLineModule类

12.编写MainModule类

13.编写App类

受篇幅限制,源码请到我的github地址查看

第五章:生命周期

5-1 基本介绍

生命周期或作用域

clipboard.png

clipboard.png

选择作用域

默认:适用于:一般实例,stateless,构造速度快如:Parser、PriceCalulatorSingleton:适用于:stateful的实例,构造速度慢的实例,必须线程安全如:数据库、网络连接Session/Request:含有session/request信息的实例、stateful的实例如:SessionSate

5-2 使用介绍

作用域的使用

作为类或者@Provides方法的属性在绑定时使用In语句@Singleton的线程安全性

第六章:切面编程

6-1 面向切面

Guice AOP

符合AOP Alliance的MethodInterceptor接口MethodInterceptor可用于“Aspects”    获取函数调用类、方法、参数    控制是否执行函数调用

实现AOP

绑定MethodInterceptor实现MethodInterceptor在MethodInterceptor中注入Dependency

代码编写

1.编写Logged类

package com.myimooc.guicedemo.aop;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;/** * @title Logged注解 * @describe 用于标识需要记录日志的方法 * @author zc * @version 1.0 2017-10-15 */@Retention(RetentionPolicy.RUNTIME)public @interface Logged {    }

2.编写LoggedInterceptor类

package com.myimooc.guicedemo.aop;import java.lang.reflect.Method;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import com.google.common.base.Joiner;/** * @title LoggedMethodInterceptor类 * @describe 切面类,用于处理被拦截的方法,实现日志记录 * @author zc * @version 1.0 2017-10-15 */public class LoggedInterceptor implements MethodInterceptor{    @Override    public Object invoke(MethodInvocation invocation) throws Throwable {                // 获得调用参数        invocation.getArguments();        // 获得调用对象        invocation.getClass();        // 获得调用方法        Method method = invocation.getMethod();                // 记录日志        System.out.println(String.format("Calling %s#%s(%s)",            method.getDeclaringClass().getName(),            method.getName(),            Joiner.on(",").join(invocation.getArguments())));                // 执行调用方法        Object result = invocation.proceed();                // 返回调用结果        return result;    }}

3.编写LoggedModule类

package com.myimooc.guicedemo.aop;import com.google.inject.AbstractModule;import com.google.inject.matcher.Matchers;/** * @title LoggedModule类 * @describe 用于配置依赖绑定 * @author zc * @version 1.0 2017-10-15 */public class LoggedModule extends AbstractModule{    @Override    protected void configure() {                // 配置拦截任意类,带有@Logged注解修饰的方法        bindInterceptor(            Matchers.any(),             Matchers.annotatedWith(Logged.class),             new LoggedInterceptor());            }}

第七章:框架集成

7-1 协作框架

使用Guice与SpringBoot协作搭建Web应用

使用SpringBoot搭建简单的Web应用使用Guice搭建业务逻辑

协作框架

clipboard.png

7-2 案例实战

创建名为guicespring的maven工程

完成后的项目结构如下

clipboard.png

受篇幅限制,源码请到我的github地址查看

协作小结

SpringBoot进行总控各自绑定Guice Injector和Spring ApplicationContext注意对象生命周期

第八章:课程总结

8-1 适用场景

Guice与Spring

Guice不是Spring的重制版Spring绑定    配置文件体现完整装配结构    大量使用字符串:实例名:属性名    在Config Time完成组装Guice绑定    Java代码描述绑定规则    每个注入和绑定仅描述局部依赖    没有Config Time

Guice的优点

代码量少性能优异支持泛型Constructor绑定:Immutable objects,不再需要getter/setter强类型易于重构

Guice的缺点

Module和绑定规则不易理解文档教程少,社区资源少无法方便搭出特殊结构:如循环依赖Guice仅仅是依赖注入框架,而Spring涵盖较多

从Spring迁移到Guice

不建议Spring与Guice整合

新项目需要选择Dependency Injection方案

不妨尝试Guice与其它组件或解决方案整合:注意对象生命周期

8-2 课程回顾

课程回顾

什么是GuceDependency Injection:改造Hello World程序注入(Injection)绑定(Binding)作用域或生命周期(Scope)Guice AOP使用Guice与SpringBoot协作搭建Web应用

转载地址:http://sveel.baihongyu.com/

你可能感兴趣的文章
可以用于switch语句的判断的数据类型总结
查看>>
MyBatis 总结
查看>>
Java多线程同步器
查看>>
Boyer-Moore高质量实现代码详解与算法详解
查看>>
MyBatis集合查询示例
查看>>
Java方法的重载
查看>>
weblogic 代码备份及部署重启
查看>>
第一章 NodeJs安装与配置
查看>>
ASP.NET分页组件
查看>>
动态规划
查看>>
Android webview使用详解
查看>>
Confluence 6 配置白名单
查看>>
input标签内容改变的触发事件
查看>>
Zabbix 监控问题总结 (3.0)
查看>>
Elasticsearch 集群优化篇
查看>>
Chris Dixon谈体验经济的崛起,及其对创业公司的重要性
查看>>
ecshop模板商品详情页显示供货商
查看>>
搜索引擎优化的10条军规矩
查看>>
YII之yiic创建YII应用
查看>>
MySQL引擎
查看>>