摘要:时间年月日星期六说明本文部分内容均来自慕课网。慕课网教学源码学习源码第一章课程介绍课程简介是啥读音是轻量级的依赖注入框架说明一个的框架需要有基础什么是剥离注入轻量级代码少易维护性能优异,跟比较。
时间:2017年10月14日星期六
说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com
教学源码:https://github.com/zccodere/s...
学习源码:https://github.com/zccodere/s...
Google Guice:Guice是啥
Guice读音:juice Guice is a lightweight dependency injection framework for java Guice 是轻量级的依赖注入框架
Google Guice:说明
Java:一个java的框架、需要有java基础 dependency injection:什么是dependency、剥离dependency、注入dependency lightweight:轻量级(代码少、易维护、性能优异),跟Spring比较。 但是:学习曲线陡峭、对开发者的要求太高了
课程目标
理解、重新理解dependency injection 掌握Guice的语法,更要掌握Guice的设计理念 开始在你的下一个项目中使用Guice
课程要点
什么是Guice dependency injection:改造Hello World程序 注入(Injection) 绑定(Binding) 作用域或生命周期(Scope) Guice AOP 使用Guice和SpringBoot协作搭建一个简单的Web应用 Guice vs Spring1-2 产生原因
Spring的不足
手动配置:使用xml进行配置,配置太过庞大 自动配置:Spring提供了自动配置,复杂项目无法实现
Guice不同于Spring
取消xml 取消bean的概念 使用Constructor来注入 泛型支持 一个专注于Dependency Injection的框架
参考资料
https://github.com/google/guice/wiki/Motivation https://github.com/google/guice/wiki/ExternalDocumentation 更多利用英文资料,如Stackoverflow第二章:理解依赖 2-1 基础配置
Hello Guice
配置Guice环境 Dependency Injection基础 改造Hello World
创建名为guicedemo的maven工程pom如下
2-2 依赖分析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
经典Hello World分析
核心算法:将指定内容输出至指定目标
改造Hello World程序
面向对象化 消除Dependency 用Guice来配置Dependency2-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小结
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 ProviderstringProvider; @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) @BindingAnnotation public @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小结
第三章:注入依赖 3-1 基本注入注入图解
注入(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
如何注入Provider
DatabaseConnection dbConn Provider< DatabaseConnection > dbConnProvider Guice会考虑对象生命周期 需要时可以自己实现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 ProvidersessionIdProvider; @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) @BindingAnnotation public @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 绑定详解
绑定图解
绑定
类名绑定 实例绑定 连接绑定 Provider绑定 命名绑定 泛型绑定 集合绑定4-2 模块组织
Module的相互关系
并列:Guice.createInjector(module1,module2,…) 嵌套:install(module) 覆盖:Modules.override(module1).with(module2)
Module何时被运行
Module里存放了很多表达式 Module不被“运行” Guice.createInjector()时记录所有表达式
系统何时初始化
没有“初始化”概念,没有Spring的Configuration Time injector.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 基本介绍生命周期或作用域
选择作用域
默认:适用于:一般实例,stateless,构造速度快 如:Parser、PriceCalulator Singleton:适用于:stateful的实例,构造速度慢的实例,必须线程安全 如:数据库、网络连接 Session/Request:含有session/request信息的实例、stateful的实例 如:SessionSate5-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搭建业务逻辑
协作框架
7-2 案例实战创建名为guicespring的maven工程
完成后的项目结构如下
受篇幅限制,源码请到我的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 课程回顾
课程回顾
什么是Guce Dependency Injection:改造Hello World程序 注入(Injection) 绑定(Binding) 作用域或生命周期(Scope) Guice AOP 使用Guice与SpringBoot协作搭建Web应用
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/67793.html
摘要:入门篇学习总结时间年月日星期三说明本文部分内容均来自慕课网。主要的功能是日志记录,性能统计,安全控制,事务处理,异常处理等等。 《Spring入门篇》学习总结 时间:2017年1月18日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/zccodere/s...个人学习源码:https://git...
摘要:拦截器学习总结时间年月日星期六说明本文部分内容均来自慕课网。慕课网教学示例源码暂无。拦截器不依赖与容器,过滤器依赖与容器。拦截器只能对请求起作用,而过滤器则可以对几乎所有的请求起作用。共性问题在拦截器中处理,可以减少重复代码,便于维护。 《SpringMVC拦截器》学习总结 时间:2017年2月18日星期六说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.co...
摘要:时间年月日星期一说明本文部分内容均来自慕课网。多用于网络加密。散列函数函数或消息摘要函数主要作用散列函数用来验证数据的完整性。 时间:2017年4月10日星期一说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/zccodere/s...个人学习源码:https://github.com/zccodere...
摘要:时间年月日星期日说明本文部分内容均来自慕课网。这对所有形态的工厂模式都是重要的这个系统的产品有至少一个的产品族同属于一个产品族的产品是设计成在一起使用的。 时间:2017年08月27日星期日说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学源码:https://github.com/zccodere/s...学习源码:https://github.c...
摘要:时间年月日星期日说明本文部分内容均来自慕课网。慕课网教学示例源码无个人学习源码第一章课程概述课程介绍课程须知本课程面向所有使用语言进行开发的小伙伴。 时间:2017年05月21日星期日说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:无个人学习源码:https://github.com/zccodere/s... 第一章:课程概述 1-1 ...
阅读 2724·2021-11-17 09:33
阅读 3067·2021-10-25 09:44
阅读 1160·2021-10-11 10:59
阅读 2351·2021-09-27 13:34
阅读 2872·2021-09-07 10:19
阅读 2090·2019-08-29 18:46
阅读 1474·2019-08-29 12:55
阅读 897·2019-08-23 17:11