精华内容
下载资源
问答
  • JAVA 设计模式手册

    2012-12-24 11:59:50
    java设计模式手册,对于初学java的人对设计模式有一定了解。
  • java设计模式手册

    2019-03-21 01:48:44
    NULL 博文链接:https://cjh820425.iteye.com/blog/955549
  • Sunny在CSDN技术博客中陆续发表了100多篇与设计模式学习相关的文章,涵盖了七个面向对 象设计原则和24个设计模式(23个GoF设计模式 + 简单工厂模式),为了方便大家学习,现将 所有文章的进行了整理,方便大家下载...
  • java设计模式包括创建型,结构型,行为型。本手册分门别类的讲述了各个模式的类与对象,包括概览图,各个模式的适用性等等。
  • 内含23种java设计模式源码示例以及阿里的开发手册,掌握这两个,写出来代码档次就会提升几个级别,个人感觉框架什么的都只是工具,而真正掌握java面向对象的内涵才是真实力,好似一个人修炼武功的内力与招式
  • JAVA设计模式_手册

    2011-06-25 07:17:25
    JAVA设计模式_手册,解析java模式的奥秘
  • java设计模式迷你手册.rar 精练经典
  • java设计模式电子书

    2012-02-03 17:47:51
    对于java设计模式深入浅出的剖析,实例通俗易懂,容易上手
  • Java 面经手册·小傅哥.pdf

    千次下载 2021-01-26 09:52:27
    这是一本以面试题为入口讲解 Java 核心内容的技术书籍,书中内容极力的向你证实代码是对数学逻辑的具体实现。当你仔细阅读书籍时,会发现Java中有大量的数学知识,包括:扰动函数、负载因子、拉链寻址、开放寻址、...
  • 阿里内部Java工程师所遵循的开发规范,涵盖编程规约、单元测试规约、异常日志规约、MySQL规约、工程规约、安全规约等,这是近万名阿里Java技术...还包含java基础泛型、反射、注解,java高级特性、设计模式等介绍等。
  • 距离《重学Java设计模式》这本PDF书籍???? 7月12日出炉以后,因为工作内容时间加长,已经有两周没有推文了,对我自己来说还蛮不习惯的。也同时让我感悟到,除了上学阶段以后,想给自己投入时间真的不容易。 就像说...

    在这里插入图片描述
    作者:小傅哥
    博客:https://bugstack.cn

    😄沉淀、分享、成长,让自己和他人都能有所收获!

    一、前言

    😬距离《重学Java设计模式》这本PDF书籍📚 7月12日出炉以后,因为工作内容时间加长,已经有两周没有推文了,对我自己来说还蛮不习惯的。也同时让我感悟到,除了上学阶段以后,想给自己投入时间真的不容易。

    就像说365天,天天重复奋斗,那只能叫做劳动辛苦,不能算作给自己的努力。

    有时候人之所以穷,是连时间都不是自己的,可用在自己身上的时间少之又少。就像有些人的时间一天等于80元、也有些人的时间一天等于8000元。可是努力是自己的事情,只能从空闲的娱乐、睡眠中压缩时间来提升自己,让以后的人生可以更多的支配自己的时间。

    你努力的样子最晒,加油!

    二、羞答答的成绩

    😄我写文章一般喜欢写系列的专题内容,想一系列的知识统一整理输出。这样既能让我有一个技术栈的总结,也能让读者有连贯性的收获。除此之外,还比较方便整理成PDF书籍,算是以外收获。

    近一年为止完成了两本PDF书籍,《字节码编程》和《重学Java设计模式》,在上一本书籍整理的经验上,后面这本算是接近合格的产品了。

    那么这本书让我收获了哪些呢?

    1. 12天全书下载量9000份,直接分享传播2个500人群,至少被1万人获得
    2. 12天公众号涨粉1400人,最高一天涨粉600人
    3. 12天微信好友增加到1600人,2个设计模式学习群,1个满500人
    4. 12天Github:「CodeGuide | 程序员编码指南」,star✨数量增加1千,目前1.6k star,上了github全球推荐榜
    5. 12天个人博客最高PV破3千,日均在1千
    6. 12天书籍推文阅读量2.3k,36人赞赏「平安是福、王刚、旅人、候、时光之刃、风、Pluto、风封尘之魂、一只天蝎座的猫、cafe babe、红枫、追梦、晓晨sama、past->now->future、蜗牛、杨萌、ithuangqing(庆哥)、春夏秋冬、小土匪、阳、郝从心、fc7395fa04ab541b、夏天不吃西瓜吃什么、宋亚东、天青色等烟雨、lemonchan、厚德载物、贝贝爸爸、!sssss、小爽、xzc、付韬🌲、L、权奥、暴走的牛德滑、宋承展」

    这些所有的数据成绩,都来自伙伴的大力支持「点赞、分享、留言、在看」。也有同好号主的转载:帅地、cxuan、蓉李纪 还有一部分盗版的帮忙,他们费尽心思删除原创作者信息,大肆分享! 不管如何毕竟我也是以学习沉淀为目的,能让更多人的学习到技能,也是很开心的。

    三、分享一波突破技术瓶颈的书籍

    以下书籍内容,点击阅读原文直达!

    🔖 目录

    🐾 一、推荐

    - 小傅哥的《重学 Java 设计模式》 ⭐⭐⭐⭐

    本书是作者小傅哥,投入50天时间,从互联网实际业务开发中抽离出,交易、营销、秒杀、中间件、源码等22个真实业务场景,编写了18万字271页的实战型Java编程资料。如果书中含有不易理解的内容,一定是作者在编写的过程中缺少必要的描述和严格的校准,感谢把你的意见或者疑问提交给我,也欢迎与我多一些交互,互相进步共同成长。

    - 小傅哥的《字节码编程》 ⭐⭐⭐

    让人怪不好意思的,说是出书有点膨胀,毕竟这不是走出版社的流程,选题、组稿、编著、审读、加工到出版发行。但全书共计107页,11万7千字,20个章节涵盖三个字节码框架(ASM、Javassist、Byte-budy)和JavaAgent使用并附带整套案例源码!

    - 《JAVA核心知识点整理》 ⭐⭐⭐⭐

    一份整理的蛮不错的Java核心知识点。覆盖了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。

    - 计算机是怎样跑起来的(日)矢泽久雄 ⭐⭐⭐⭐⭐ - 点击购买(支持作者)

    矢泽久雄,曾在Software House做过程序员,电脑作家之友会会长。工作之余笔耕不辍,从电路到编程语言均有涉及。代表作有《程序是怎样跑起来的》等。本书以图配文,以计算机的三大原则为开端、相继介绍了计算机的结构、手工汇编、程序流程、算法、数据结构、面向对象编程、数据库、TCP/IP 网络、数据加密、XML、计算机系统开发以及SE 的相关知识。

    - cxuan的《程序员必知的硬核知识大全》 ⭐⭐⭐⭐

    浓缩了 CPU、内存、二进制、计算机硬件、应用、算法 的精华知识,以通俗易懂的形式给你讲出来,读者看完后一致好评,cxuan 呕心沥血的作品,文字是一行一行写的,图是一笔一笔画的,强烈推荐给大家。

    ☕️ 二、Java

    1. 《Java虚拟机规范(Java SE 7)》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    如果不太熟悉jvm,这个读起来非常乏味(只有规范,没有多余解释),但如果阅读过相关深入java虚拟机,再读这个,会非常有亲切感。

    2. 《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    这是一部从工作原理和工程实践两个维度深入剖析JVM的著作,是计算机领域公认的经典,繁体版在台湾也颇受欢迎。作者周志明,是资深Java技术、机器学习和企业级开发技术专家,现任远光软件研究院院长,人工智能博士在读。

    3. 《JAVA核心知识点整理》⭐⭐⭐⭐

    一份整理的蛮不错的Java核心知识点。覆盖了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。

    4. 《On Java 8 编程思想》⭐⭐⭐⭐

    本书原作者为 [美] Bruce Eckel,即《Java 编程思想》的作者。译者在翻译中同时参考了谷歌、百度、有道翻译的译文以及《Java编程思想》第四版中文版的部分内容(对其翻译死板,生造名词,语言精炼度差问题进行规避和改正)。最后结合译者自己的理解进行本地化,尽量做到专业和言简意赅,方便大家更好的理解学习。

    5. 深入浅出+Java+多线程 ⭐⭐⭐⭐

    笔者在读完市⾯上关于Java并发编程的资料后,感觉有些知识点不是很清晰,于是
    在RedSpider社区内展开了对Java并发编程原理的讨论。鉴于开源精神,我们决定
    将我们讨论之后的Java并发编程原理整理成书籍,分享给⼤家。
    如果您或者您的单位愿意赞助本书或本社区,请发送邮件到RedSpider社区邮件组redspider@qun.mail.163.com或加微信redspider-worker进⾏洽谈。

    6. 《Java核心技术 I》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    不同于一般的 Java入门书,此书对api的讲解非常详细,细节部门颇多。举个例子,java对象序列化时会写入什么内容,本书都有详细的介绍

    7. 《effective java 3》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    全书以一种比较松散的方式将这些条目组织成11章,每一章都涉及软件设计的一个主要方面。因此,本书并不一定需要按部就班地从头读到尾,因为每个条目都有一定程度的独立性。这些条目相互之间经常交叉引用,因此可以很容易地在书中找到自己需要的内容。

    8. 《Java解惑》 ⭐⭐⭐

    挺有意思的一本书,它列举了许多平常不太注意的细节问题,可能大部分时候我们都不会碰到此类问题,但如果读过,一旦碰到,就会留意此类问题。

    9. 《Thinking In Java 4》 ⭐⭐⭐⭐⭐ - 点击购买(支持作者)

    值得用2年深入抚摸的书籍,对于学习java技术除了最开始的入门书籍后,这是一本非常值得阅读的书籍。

    10. 《Java内存模型》 ⭐⭐⭐⭐

    Java线程之间的通信由Java内存模型(本文简称为JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。

    11. 《Java并发编程实践(全)》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,还阐释了创造它们的原因,及其背后的设计模式。

    12. 《Spring揭秘》 ⭐⭐⭐⭐⭐ - 点击购买(支持作者)

    本书内容全面,论述深刻入理,必将成为每个Java专业开发人员必备的Spring图书。

    难得的国产良心技术书籍,既没有大量堆砌Spring源码,也没有原封不动地翻译官方文档。作者以自己的深厚功力和独特视角一步一步地把Spring框架抽丝剥茧地展现在读者面前,从谋篇布局和字里行间都能看出作者的用心之处。如果你想深入了解Spring的方方面面,这本书非读不可,而且读一遍都不够,要每隔一段时间反复阅读,尤其第二部分IOC和第三部分AOP,它们是Spring的基础,也是这本书的精华所在。这里不妨给个建议,以这本书为蓝本把Spring框架用到的设计模式和原则认真梳理一遍,结合源码认真理解为何要这样设计。如若这样,假以时日,功力必有小成啊。最后感谢作者,感谢我能遇到这本书

    13. 《Spring源码深度解析》 ⭐⭐⭐ - 点击购买(支持作者)

    由浅入深、由易到难地对Spring源码展开了系统的讲解,包括Spring的设计理念和整体架构、容器的基本实现、默认标签的解析、自定义标签的解析、bean的加载、容器的功能扩展、AOP、数据库连接JDBC、整合MyBatis、事务、SpringMVC、远程服务、Spring消息服务等内容。

    14. 《深入理解SpringCloud与微服务构建》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    本书以微服务的基本概念介绍性开篇,逐步引出Java平台下打造微服务的利器SpringBoot微框架。书中从SpringBoot微框架的“出身”开始,循序渐进,为大家剖析SpringBoot微框架的设计理念和原理,并对框架的重点功能和模块进行了逐一讲解。

    15. 《美团技术后台篇》 ⭐⭐⭐⭐

    2019年美团点评高级技术汇总,深入且清晰设计到Java核心技术。包括;字节码编程、全链路监控、美团分布式 ID 生成服务开源等。

    16. Java Concurrency in Practice ⭐⭐⭐⭐⭐

    This book covers:
    Basic concepts of concurrency and thread safety
    Techniques for building and composing thread-safe classes
    Using the concurrency building blocks in java.util.concurrent
    Performance optimization dos and don’ts
    Testing concurrent programs
    Advanced topics such as atomic variables, nonblocking algorithms, and the Java Memory Model

    💾 三、DB

    1. 《MySQL王者晋级之路》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    十年磨一剑,汇集作者多年MySQL数据库领域的一线实战与教学经验,由浅入深剖析MySQL的体系结构、备份恢复、复制、高可用集群架构、优化、故障排查、新版本特性、监控、升级及技术面试宝典等知识点。

    2. 《数据库索引设计与优化》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    作者通过系统的讲解及大量的案例清晰地阐释了关系型数据库的访问路径选择原理,以及表和索引的扫描方式,详尽地讲解了如何快速地估算SQL 运行的CPU 时间及执行时间,帮助读者从原理上理解SQL、表及索引结构、访问方式等对关系型数据库造成的影响,并能够运用量化的方法进行判断和优化,指导关系型数据库的索引设计。此书适用于已经具备了SQL 这一关系型语言相关知识,希望通过理解SQL 性能相关的内容,或者希望通过了解如何有效地设计表和索引而从中获益的人员。

    🎈 四、Redis

    1. 《Redis设计与实现》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    黄健宏 软件开发者,他喜欢函数式编程,热爱开源软件。出于对数据库的强烈兴趣,他开始阅读和分析 Redis 源代码,并对 Redis 2.6 和 Redis 3.0 的源代码进行了详细注释。

    2. 《Redis 深度历险:核心原理与应用实践》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    作者:钱文品,老钱。可以说这是一本深挖到redis骨头的技术书籍,整个内容涵盖;基础和应用篇、原理篇、集群篇、拓展篇、源码篇共 5 大块内容,值得学习。

    3. 《Redis开发与运维》 ⭐⭐⭐⭐- 点击购买(支持作者)

    付磊,张益军 | 搜狐视频高级研发工程师,都拥有多年Redis开发运维经验,为公司多个核心业务提供Redis服务。两人共同编写了本书,在本书中全面讲解Redis基本功能及其应用,并结合线上开发与运维监控中的实际使用案例,深入分析并总结了实际开发运维中遇到的“陷阱”,以及背后的原因, 包含大规模集群开发与管理的场景、应用案例与开发技巧,为高效开发运维提供了大量实际经验和建议。

    🎨 五、架构&设计

    1. 《代码整洁之道》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    本书提出一种观念:代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。作为编程领域的佼佼者,本书作者给出了一系列行之有效的整洁代码操作实践。

    2. 《Head_First设计模式(中文版)》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    Head First陆续的介绍了策略模式、观察者模式、装饰者模式、工厂方法模式、抽象工厂模式、单件模式、命令模式、适配器模式、外观模式、模板方法模式、迭代器模式、组合模式、状态模式、代理模式,在介绍各种模式的期间,用简单的应用场景、通俗的语言引导读者去思考这些模式是如何利用和遵循相应OO原则的,然后再清晰的总结出每种模式的定义。

    3. 《编写可读代码的艺术》 ⭐⭐⭐ - 点击购买(支持作者)

    细节决定成败,思路清晰、言简意赅的代码让程序员一目了然;而格式凌乱、拖沓冗长的代码让程序员一头雾水。除了可以正确运行以外,优秀的代码必须具备良好的可读性,编写的代码要使其他人能在最短的时间内理解才行。本书旨在强调代码对人的友好性和可读性。

    🍭 六、号主原创书籍[免费下载]

    1. 小傅哥的《字节码编程》 ⭐⭐⭐

    让人怪不好意思的,说是出书有点膨胀,毕竟这不是走出版社的流程,选题、组稿、编著、审读、加工到出版发行。但全书共计107页,11万7千字,20个章节涵盖三个字节码框架(ASM、Javassist、Byte-budy)和JavaAgent使用并附带整套案例源码!

    2. 小傅哥的《重学 Java 设计模式》 ⭐⭐⭐⭐

    本书是作者小傅哥,投入50天时间,从互联网实际业务开发中抽离出,交易、营销、秒杀、中间件、源码等22个真实业务场景,编写了18万字271页的实战型Java编程资料。如果书中含有不易理解的内容,一定是作者在编写的过程中缺少必要的描述和严格的校准,感谢把你的意见或者疑问提交给我,也欢迎与我多一些交互,互相进步共同成长。

    3. 《Java 基础核心总结》 ⭐⭐⭐

    这本 PDF 非常适合 Java 小白和其他语言转型的程序员,涉及的面非常广、语言比较简练,通俗易懂的把 Java 所有特性、语法概念都给你讲出来,这是第一版,以后还会持续更新,推荐给小伙伴们。

    4. 《HTTP 超全汇总》 ⭐⭐⭐

    把关于 HTTP 协议 90% 的内容都讲出来了,非常全的一本 PDF,可以作为速查手册,也可以当作培训教材,作者写了将近两个月的作品,推荐给大家。

    5. 《程序员必知的硬核知识大全》 ⭐⭐⭐⭐

    浓缩了 CPU、内存、二进制、计算机硬件、应用、算法 的精华知识,以通俗易懂的形式给你讲出来,读者看完后一致好评,cxuan 呕心沥血的作品,文字是一行一行写的,图是一笔一笔画的,强烈推荐给大家。

    ⛳️ 七、其他系列

    1. 《阿里工程师的自我修养》 ⭐⭐⭐⭐

    从入门到进阶,从普通员工到主管,从知识到落地,从量的积累到质的飞跃,在不确定性的世界中,你遇到的种种难题,阿里工程师正在探索着最优解。3大思维、10个技巧、10年感悟……每经过一次大的战役,阿里工程师都会复盘、沉淀,这些经验值得细品。

    2. 《Http权威指南》 ⭐⭐⭐⭐ - 点击购买(支持作者)

    如果以前没有深入了解http,读了此书,会觉得以前了解的关于http的内容都弱爆了。经典书籍,中文版2012年发版,翻译的还不错,值得阅读。

    3. Elasticsearch 权威指南 中文版 ⭐⭐⭐⭐ - 点击购买(支持作者)

    这本指南都会帮助你了解其中最基本的概念,从最基本的操作开始学习 Elasticsearch。同时将向你介绍讲解结构化搜索、统计、查询过滤、地理定位、自动完成以及你是不是要查找的提示。并且探讨如何给数据建模能提升 Elasticsearch 的性能,以及在生产环境中如何配置、监视你的集群。

    4. 计算机是怎样跑起来的(日)矢泽久雄 ⭐⭐⭐⭐⭐ - 点击购买(支持作者)

    矢泽久雄,曾在Software House做过程序员,电脑作家之友会会长。工作之余笔耕不辍,从电路到编程语言均有涉及。代表作有《程序是怎样跑起来的》等。本书以图配文,以计算机的三大原则为开端、相继介绍了计算机的结构、手工汇编、程序流程、算法、数据结构、面向对象编程、数据库、TCP/IP 网络、数据加密、XML、计算机系统开发以及SE 的相关知识。

    5. 编码:隐匿在计算机软硬件背后的语言 ⭐⭐⭐⭐⭐ - 点击购买(支持作者)

    是一本讲述计算机工作原理的书。不过,你千万不要因为“工作原理”之类的字眼就武断地认为它是晦涩而难懂的。作者用丰富的想象和清晰的笔墨将看似烦杂的理论阐述得通俗易懂,你丝毫不会感到枯燥和生硬。更重要的是,你会因此更加深刻地理解计算机的工作原理。这种理解不是抽象层面上的,而是具有一定深度的,这种深度甚至不逊于“电气工程师”和“程序员”的理解。

    6. 计算机程序的构造和解释(原书第2版) ⭐⭐⭐⭐⭐

    《计算机程序的构造和解释(原书第2版)》1984年出版,成型于美国麻省理工学院(MIT)多年使用的一本教材,1996年修订为第2版。在过去的二十多年里,《计算机程序的构造和解释(原书第2版)》对于计算机科学的教育计划产生了深刻的影响。第2版中大部分重要程序设计系统都重新修改并做过测试,包括各种解释器和编译器。作者根据其后十余年的教学实践,还对其他许多细节做了相应的修改。

    7. 代码大全(第2版) ⭐⭐⭐⭐⭐

    第2版的《代码大全》是著名IT畅销书作者史蒂夫·迈克康奈尔11年前的经典著作的全新演绎:第2版不是第一版的简单修订增补,而是完全进行了重写;增加了很多与时俱进的内容。这也是一本完整的软件构建手册,涵盖了软件构建过程中的所有细节。它从软件质量和编程思想等方面论述了软件构建的各个问题,并详细论述了紧跟潮流的新技术、高屋建瓴的观点、通用的概念,还含有丰富而典型的程序示例。

    8. 编程匠艺 ⭐⭐⭐⭐

    如果你可以编写出合格的代码,但是想更进一步、创作出组织良好而且易于理解的代码,并希望成为一名真正的编程专家或提高现有的职业技能,那么Pete Goodliffe编写的这本本书都会为你给出答案。本书的内容涵盖编程的各个要素,如代码风格、变量命名、错误处理和安全性等。此外,本书还对一些更广泛的编程问题进行了探讨,如有效的团队合作、开发过程和文档编写,等等。

    9. Zookeeper 分布式过程 ⭐⭐⭐⭐ - 点击购买(支持作者)

    作者介绍Flavio Junqueira 是微软研究院在英国剑桥大学的研究人员之一。他拥有美国加州大学圣地亚哥分校计算机科学博士学位。他的研究范围涉及分布式系统的各个方面,包括分布式算法、并发性和可扩展性。他是Apache项目如Apache ZooKeeper(PMC主席和提交者)和Apache BookKeeper(提交者)的积极贡献者。他一有空就喜欢睡觉。

    😄 八、人性

    • 《非暴力沟通》(美)卢森堡
    • 《逆商:我们该如何应对坏事件》
    • 《超越自卑》阿德勒
    • 《关键对话-如何高效能沟通》
    • 《人月神话》 - 这是一本经典著作,与软件开发有关的每一个人都应该不止一遍地读这本书

    以上PDF书籍链接皆来自网络分享,除开源以及号主原创书籍外,其含版权书籍未提供下载链接。

    四、总结

    • 以上内容主要想分享和感谢大家,是这么多小伙伴们的宣传、分享,才让我这样的小号主将这本书传播给了更多的技术编程人员。
    • 为了防止以后再被恶意抄袭,删除原创作者信息,以后我会添加水印了。以前有强迫症,觉得水印不美观,哈哈哈。好吧!
    • 书中22个真实场景案例模拟、18万字271页的打造,希望到你手里不是落灰的沉淀,而是真能吸收,学习。关注公众号:bugstack虫洞栈,回复PDF获取
    展开全文
  • 《重学Java设计模式》PDF,我的第二本电子书,截止目前为止全网下载量4.0万本。这是一本以实战真实场景编码的方式学习设计模式,全书涉及交易、营销、下单、秒杀、规则引擎以及中间件等22个真实场景,共计18万字271...


    作者:小傅哥
    博客:https://bugstack.cn

    沉淀、分享、成长,让自己和他人都能有所收获!😄

    一、前言

    1. 先祝贺下自己拿下4.0万本下载量!

    《重学Java设计模式》PDF,我的第二本电子书,截止目前为止全网下载量4.0万本。这是一本以实战真实场景编码的方式学习设计模式,全书涉及交易、营销、下单、秒杀、规则引擎以及中间件等22个真实场景,共计18万字271页,耗时50天肝完!文末提供下载指引

    当然这本书的推广少不了粉丝的支持,也感谢我的号主朋友帮忙转载分享。也有使用此书籍为自己拉粉的号主,同样也感谢你们为这本书做的宣传,让更多人可以学习到有用的设计模式

    2. 有个好身体才能继续前行!

    10月4日,终于从医院🏥驱车250公里从张家口回来了!在医院陪床真心不容易,还好不是麻烦的病,只是做一个腰间盘里的微创。哈哈哈,什么都还好,只是好几天没洗澡了,睡觉也没脱衣服。 在医院基本除了简单的看护外,基本都是闲呆。但闲不住的我终于还是把电脑打开了,就像下面这样!

    小傅哥 & 医院陪床敲代码

    3. 为Java面经又肝出一本PDF!

    做到让懂了就是真的懂!这绝对不是一本简单的面试手册,也不是单纯的面试题。而是借着面试的场景深入讲解Java核心知识,就像学习过可以深入理解:HashMap的扰动函数让散列更均匀、ThreadLocal使用斐波那契黄金分割点散列、双端队列的用途、红黑树与2-3树的关系、洗牌算法等等核心知识。

    二、简介

    Hello,world of java! 你好,java编码的世界!

    欢迎来到这里,很高兴你能拿到这本书。如果你能坚持看完并按照书中的实践例子进行撸码学习,那么一定会有非常深刻的收获。

    这是一本借着面试的名义讲解 java 核心知识点的书籍,很多知识都是你平常在用的,但可能忽略了很多细节部分。就像,HashMap的扰动函数让散列更均匀、除了这种散列还有ThreadLocal可以使用斐波那契黄金分割点散列等等,一系列知识点都有在本书中通过实践的方式向你深度讲解。

    让懂了就是真的懂

    让懂了就是真懂,是本书的核心宗旨。对每一个需要深入了解的知识点,都从最基本的原理进行剖析。再通过可以实践验证的例子,来学习这些核心知识点,让学习内容既可以简单,也可以更深入。

    1. 面试真的只是造火箭吗?

    常说面试造火箭,入职拧螺丝。但你真的有造火箭的本事吗,大部分都是不敢承认自己的知识盲区和技术瓶颈以及经验不足的自嘲。

    面试时

    • 我希望你懂数据结构,因为这样的你在使用HashMap、ArrayList、LinkedList,更加得心应手。
    • 我希望你懂散列算法,因为这样的你在设计路由时,会有很多选择;除法散列法平方散列法斐波那契(Fibonacci)散列法等。
    • 我希望你懂开源代码,因为这样的你在遇到问题时,可以快速定位,还可能创造出一些系统服务的中间件,来更好的解耦系统。
    • 我希望你懂设计模式,因为这样的你可以写出可扩展、易维护的程序,让整个团队都能向更好的方向发展。

    所以,从不是CRUD选择了你,也不是造螺丝让你成为工具人。而是你的技术能力决定你的眼界,眼界又决定了你写出的代码!

    2. 适合人群

    1. 具备一定编程基础,工作2年以上的研发人员
    2. 希望突破自己阶段性的瓶颈期,可以有更深入的技术成长
    3. 有意愿成为架构师,但还找不到一个方向
    4. 面试求职,唠最狠的嗑,拿最贵的offer

    3. 我能学到什么

    1. 学习Java中常用API的数据结构和算法
    2. 深入学习扰动函数、负载因子、红黑树、斐波那契等核心知识点
    3. 打破学习瓶颈,让实践方式的学习思路,给自己增加更多的知识

    4. 阅读建议

    小傅哥,系列专题文章都偏向于实践落地,每一章节的内容都有对应的案例代码作为验证。所以学习的过程最好也要亲手试验下,这样才可以更加深入的学到书中的精髓部分。事必躬亲,加油!

    三、PDF📚下载

    下载前,一点对原创作者的支持请求😬,点赞在看分享留言赞赏,完成任何一样都可以获得🉐这本PDF书籍。

    1. 可获得内容包括

    1. 《Java 面经手册》PDF 书籍一本
    2. 全书学习对应源码案例一套
    3. 在线阅读版学习了资料

    2. 获取方式

    我写了三本PDF书,你都可以关注公众号:bugstack虫洞栈 回复以下口令,进行下载!

    1. 《Java 面经手册》,公众号内回复:面经手册,获取下载链接。
    2. 《重学Java设计模式》,公众号内回复:设计模式,获取下载链接。
    3. 《字节码编程》,公众号内回复:字节码编程,获取下载链接。
    4. 也可以添加小傅哥微信(fustack)加入学习群,互相交流。

    四、收个尾🎉

    让懂了就是真的懂!

    学习编程最重要的不是背理论、背结果,也不是为了面试就疯狂的搜集资料背答案。这些都不能让你有很大的收获,可能还会适得其反。万一你背错了,很容易被拆穿!

    而对于我们编码这一行来说,如果不想被这个行业淘汰,几乎是需要每天都学习!尤其是感觉到自己到了一定的瓶颈期,又很难成长上去的时候。什么时候是瓶颈期? 如果你不能过阿里的P7、也不能过京东的T7等等,互联网行业中一些门槛较高的职位时,那么就是处于一个技术瓶颈期。

    时间管理?,想想自己好像也没有什么时间管理,只不过一年没有玩过游戏了。大部分时间都会投入自己学习中,梳理资料、编写文章、技术交流上。尤其是资料的梳理编写博客上,让我自己有了很大的技术进步,同时又有了不错的文笔进步。这是我近一年最大的收获!

    最后,这不是面经手册终结,后续还再继续!沉淀、分享、成长,让自己和他人都能有所收获!

    展开全文
  • 设计模式的pdf文档,让你读懂java设计模式。 java开发规范手册 , 让你开发更规范。
  • 设计模式迷你手册

    2014-02-27 16:38:20
    有图有表,居家旅行必备,就是方便.包含c++,java,c#的类库实例.
  • java设计模式源代码(23种设计模式标准代码) 以及方便查询的设计模式帮助手册
  • Java中除去有设计原则之外,还有23中设计模式。(设计模式我们主要来将思想和精髓的地方,除去Java还有其他的语言也可以适用) 这些模式都是前辈们一点一点积累下来,一直在改进,一直在优化的,这些设计模式可以...

    Java中除去有设计原则之外,还有23中设计模式。

    这些模式都是前辈们一点一点积累下来,一直在改进,一直在优化的,而这些设计模式可以解决一些特定的问题。

    并且在这些模式中,可以说是将语言的使用体现的淋漓尽致。

    那我们今天要学习  创建型模式  中的  抽象工厂模式  !

    抽象工厂模式:

    大家可以发现啊,这个之前我们说了这个工厂模式,但是现在怎么多了一个抽象工厂模式?是不是,它和工厂模式有啥区别,如何理解抽象这个词的,为啥会有俩工厂模式?

    我们带着这些个以为来看这篇博客。

    先来说说什么是抽象工厂模式:

    抽象工厂呢就是一个超级工厂, 它是用来创建其他工厂,就相当于我们之前的那个博客的面粉厂一样,我们除去面粉厂之外,还得需要一个馅料厂(不能光吃饺子皮吧,饺子得有馅料吧),这时候,我们定义一个超级工厂,也就是抽象工厂,我们用这个超级工厂来管理其他的这些个工厂。

    这么一说,上面的这些个问题都知道了答案了。接下来我们来实现一下简单的抽象工厂,来体验一下。

    抽象工厂模式的实现:

    我们的那个面粉厂暂时先不动,再相同的创建一个馅料厂。

    先弄个馅料的接口,然后接口中添加和馅料的方法。相同的,具体和啥馅料,我们让具体的实现类来决定。

    然后,我想吃韭菜鸡蛋馅的,我就先弄个韭菜鸡蛋的馅,让它去实现这个馅料接口。

    除去这个韭菜鸡蛋,我再弄个黑暗料理,花生酱鱿鱼须馅的。

    原本在工厂模式中,接下来我们就要创建工厂了,但是,我们这次是弄得超级工厂,我们不按照以前的方法去做了,而是换一种思路,继续!

    第一步:抽象工厂,先得抽象,然后工厂。我们创建一个抽象工厂类。叫食品加工厂,FoodFactory,但是是抽象的。(注意命名规范,如果不知道规范的,请看阿里巴巴Java开发手册)

    大家勾选了这个abstract,就直接创建一个抽象类,方便快捷。

    第二步:我们在这个食品加工厂类中将刚刚两个工厂搞成抽象方法,这个方法主要目的是获取工厂。也就是我们上一个工厂模式介绍中的工厂中的方法。我来贴一下我们上个博客中的工厂方法。

    我们将上面方法抽象出来

    有了这个抽象工厂之后,我们这才来创建具体的工厂,并且让每一个具体的工厂,来继承这个食品加工厂!

    实现这个之后我们发现有俩方法,获取面粉的获取馅料的方法都有,但是我们是面粉厂,我们只管面粉,馅料我们是弄不了的,所以我们就不管它,就让它返回null。

    当然,还有馅料厂。

    第三步:我们还得弄个管理这俩工厂的类,用来实例化工厂。

    最后一步:我们来测试,先来做一个韭菜鸡蛋馅的饺子。

    先弄饺子面团。

    再弄饺子馅。

    这样是不是,饺子面也有了,馅也有了?

    其实上面这段代码我们看的不是很明白,或者不是很理解这个具体的架构样子,我给一个图,画的不专业,但是,绝对能够让大家看明白结构。

    大家如果有不明白的地方可以联系我,我给大家解答。

     

    展开全文
  • 《Spring2.5-中文参考手册》和《JAVA设计模式》,希望对用得着的人有用!
  • Design Patterns设计模式速查手册HandBood系列(By FengGe整理) 本人整理用于开发的实用文档、书籍、工具
  • java设计模式详细资料

    2012-05-18 10:30:32
    想深入学习高级java,从java模式入手,是一个不错的选择,对自己理解java更深层的东西,有更大的帮助。本人积累的学习资料,现拿出来共享,希望对大家有所帮助。
  • java模式

    2019-01-22 14:55:26
    本书是一本讲解设计原则以及为常见的设计模式的实用教材,目的是为工作繁忙的Java系统设计师提供一个快速...本书适合于Java程序员、架构设计师及设计模式爱好者,是一本实用的设计原则和设计模式的自学教材和使用手册
  • 设计模式Java手册源代码《Design Patterns》Complete Implementation (by Java)源代码
  • java23种设计模式彩图

    2012-08-04 22:47:56
    附件包括,java23种设计模式,整体彩图,在一张大图中,想全面了解设计模式的同学们可以看看。
  • java设计模式参考手册

    2007-10-20 12:55:18
    java设计模式参考手册
  • 在静态代理(Static Proxy)模式中,代理类都是真实存在的,由程序员提前创建好的java类,是静态的,每一个代理类在编译之后都会生成一个.class字节码文件,静态代理类所实现的接口和所代理的方法早在编译期都已被固定...

    目录

    一、什么是动态代理

    二、Java对动态代理的支持

    三、使用CGLIB实现动态代理

    四、动态代理模式的特点

     参考文章


    一、什么是动态代理

    在静态代理(Static Proxy)模式中,代理类都是真实存在的,由程序员提前创建好的java类,是静态的,每一个代理类在编译之后都会生成一个.class字节码文件,静态代理类所实现的接口和所代理的方法早在编译期都已被固定了。

    动态代理(Dynamic Proxy)则不同:动态代理使用字节码动态生成和加载技术,在系统运行时动态地生成和加载代理类。

    与静态代理相比,动态代理有以下优点:首先,无需再为每一个真实主题写一个形式上完全一样的代理类,假如抽象主题接口中的方法很多的话,为每一个接口方法写一个代理方法也很麻烦,同样地,如果后期抽象主题接口发生变动,则真实主题和代理类都要修改,不利于系统维护;其次,动态代理可以让系统根据实际需要来动态创建代理类,同一个代理类能够代理多个不同的真实主题类,并且可以代理多个不同的方法。

    二、Java对动态代理的支持

    从JDK 1.3版本开始,Java语言提供了对动态代理的支持,在Java中实现动态代理机制,需要用到 java.lang.reflect 包中的 InvocationHandler 接口和 Proxy 类,我们先来看看java的API帮助文档是怎么样对这两个类进行描述的:

    InvocationHandler 

    InvocationHandler is the interface implemented by the invocation handler of a proxy instance. 
    Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the 
    method invocation is encoded and dispatched to the invoke method of its invocation handler.
    InvocationHandler 是代理实例的调用处理程序实现的接口。
    每个代理实例都具有一个与之关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程
    序的 invoke() 方法。

    invoke() 方法形式如下:  

    Object invoke(Object proxy,Method method,Object[] args) throws Throwable

    InvocationHandler 接口只包含invoke()这唯一一个方法,该方法用于处理对代理类实例的方法调用并返回相应的结果,当一个代理实例中的业务方法被调用时将自动调用该方法。invoke()方法包含三个参数,其中第一个参数proxy表示代理类的实例,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组。 

    Proxy 

    Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass 
    of all dynamic proxy classes created by those methods. 
    Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

    Proxy提供给我们的静态方法有以下四个:  

    //返回指定代理实例的调用处理程序。
    static InvocationHandler getInvocationHandler(Object proxy) 
    
    //返回代理类的 java.lang.Class 对象,并向其提供类加载器和接口数组。
    static Class<?>	getProxyClass(ClassLoader loader, Class<?>[] interfaces) 
    
    //当且仅当指定的类通过 getProxyClass 方法或 newProxyInstance 方法动态生成为代理类时,返回 true。
    static boolean	isProxyClass(Class<?> cl) 
    
    //返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
    //方法中的 ClassLoader loader 参数用来指定动态代理类的类加载器,Class<?>[] interfaces用来指定动态代理类要实现的接口。
    //InvocationHandler h 用来指定与即将生成的动态代理对象相关联的调用处理程序
    static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

    下面我们以为数据库增加日志记录功能(为简单起见,我们仅记录下所有操作的执行时间及操作执行的结果)为例来看一看如何使用这两个类实现动态代理:

    为了使演示更清晰,在此先定义两个简单类,一个User类和一个Document类分别表示数据库中的用户记录和文档记录,其代码如下。  

    public class User {
        // 用户在数据库中的ID
        private Long id;
        // 用户的姓名
        private String name;
        public User(Long id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    public class Document {
        // 文档在数据库中的ID
        private Long id;
        // 文档的标题
        private String title;
        public Document(Long id, String title) {
            super();
            this.id = id;
            this.title = title;
        }
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
    }

    另外还需定义一个DataBase类用来扮演数据库的功能,在此为简单起见,将数据库中的用户记录和文档记录分别存储在一个Map中,代码如下。 

    import java.util.HashMap;
    import java.util.Map;
    public class DataBase {
    	private static Map<Long, User> userMap = null;
    	private static Map<Long, Document> documentMap = null;
    	// 用来记录当前登陆用户信息
    	private static User currentUser = null;
    
    	private DataBase() {
    		// 数据初始化,为数据库中增加几条用户记录。。。
    		userMap = new HashMap<Long, User>();
    		userMap.put(20160708L, new User(20160708L, "燕凌娇"));
    		userMap.put(20160709L, new User(20160709L, "姬如雪"));
    		userMap.put(20160710L, new User(20160710L, "百里登风"));
    		// 数据初始化,为数据库中增加几条文档记录。。。
    		documentMap = new HashMap<Long, Document>();
    		documentMap.put(30160708L, new Document(30160708L, "C++常用算法手册"));
    		documentMap.put(30160709L, new Document(30160709L, "深入理解Android内核设计思想"));
    		documentMap.put(30160710L, new Document(30160710L, "Java从入门到放弃"));
    	}
    
    	public User getCurrentUser() {
    		return currentUser;
    	}
    
    	public void setCurrentUser(User currentUser) {
    		DataBase.currentUser = currentUser;
    	}
    
    	public Map<Long, User> getUserMap() {
    		return userMap;
    	}
    
    	public Map<Long, Document> getDocumentMap() {
    		return documentMap;
    	}
    
    	public static DataBase getDataBaseInstance() {
    		return DataBaseHolder.dataBase;
    	}
    
    	public static class DataBaseHolder {
    		private static DataBase dataBase = new DataBase();
    	}
    }

    数据库布置完成了,接下来开始写动态代理相关代码了,为了与静态代理进行比较,在此我们来创建两个接口(抽象主题角色)。 

    public interface UserDao {
        // 登陆数据库,为了演示方便将字符串作为执行结果返回
        String login(Long id);
        // 退出数据库,为了演示方便将字符串作为执行结果返回
        String logout();
    }
    public interface DocumentDao {
        // 新增文档,为了演示方便将字符串作为执行结果返回
        String add(Document document);
        // 删除文档,为了演示方便将字符串作为执行结果返回
        String delete(Document document);
    }

    接下来是两个真实主题角色,ImpUserDao 类和ImpDocumentDao类,为了使示例结果清晰,此处将接口的执行结果直接以字符串形式返回。

    public class ImpUserDao implements UserDao {
    	@Override
    	public String login(Long id) {
    		User user = DataBase.getDataBaseInstance().getUserMap().get(id);
    		if (null != user) {
    			// 数据库有此用户的信息,则允许登陆...
    			DataBase.getDataBaseInstance().setCurrentUser(user);
    			return "用户[" + user.getName() + "]登陆成功...";
    		} else {
    			// 数据库没有此用户信息,则不让登陆...
    			return "登陆失败,ID为\"" + id + "\"的用户不存在!";
    		}
    	}
    
    	@Override
    	public String logout() {
    		User user = DataBase.getDataBaseInstance().getCurrentUser();
    		if (null != user) {
    			// 若当前有用户登陆,则退出成功...
    			DataBase.getDataBaseInstance().setCurrentUser(null);
    			return "用户[" + user.getName() + "]退出登陆成功...";
    		} else {
    			// 若当前无用户登陆,则退出失败...
    			return "退出登陆失败,当前无登陆用户!";
    		}
    	}
    }
    public class ImpDocumentDao implements DocumentDao {
    	@Override
    	public String add(Document document) {
    		User user = DataBase.getDataBaseInstance().getCurrentUser();
    		if (null == user) {
    			// 若当前用户未登陆,则新增文档失败...
    			return "保存失败,未获取到登陆信息!";
    		} else {
    			Document dbDocument = DataBase.getDataBaseInstance().getDocumentMap().get(document.getId());
    			if (null != dbDocument) {
    				// 若数据库中已经存在该ID的文档,则新增文档失败...
    				return "添加文档《" + document.getTitle() + "》失败,文档已存在!";
    			} else {
    				// 若该ID的文档在数据库不存在,则新增文档成功...
    				DataBase.getDataBaseInstance().getDocumentMap().put(document.getId(), document);
    				return "添加文档《" + document.getTitle() + "》成功...";
    			}
    		}
    	}
    
    	@Override
    	public String delete(Document document) {
    		User user = DataBase.getDataBaseInstance().getCurrentUser();
    		if (null == user) {
    			// 若当前用户未登陆,则新增文档失败...
    			return "保存失败,未获取到登陆信息!";
    		} else {
    			Document dbDocument = DataBase.getDataBaseInstance().getDocumentMap().get(document.getId());
    			if (null == dbDocument) {
    				// 若数据库中该文档不存在,则删除文档失败...
    				return "删除文档《" + document.getTitle() + "》失败,文档不存在!";
    			} else {
    				// 若数据库中该文档存在,则删除文档成功...
    				DataBase.getDataBaseInstance().getDocumentMap().remove(document.getId());
    				return "删除文档《" + document.getTitle() + "》成功...";
    			}
    		}
    	}
    }

    最后,我们就要定义动态代理类了,前面说过,每一个动态代理类都必须要实现 InvocationHandler 这个接口,因此我们这个动态代理类也不例外。 

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    
    public class DataBaseLogHandler implements InvocationHandler {
    	private Object object;
    	private Calendar calendar;
    
    	public DataBaseLogHandler(Object object) {
    		super();
    		this.object = object;
    	}
    
    	// invoke()方法用于处理对代理类实例的方法调用并返回相应的结果
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		before(method);
    		// 继续转发请求给内部真实主题角色
    		Object result = method.invoke(object, args);
    		after(result);
    		if (method.getName().equalsIgnoreCase("logout")) {
    			System.out.println("**********************************");
    			System.out.println("");
    		}
    		return result;
    	}
    
    	public void before(Method method) {
    		calendar = new GregorianCalendar();
    		int year = calendar.get(Calendar.YEAR);
    		int month = calendar.get(Calendar.MONTH);
    		int date = calendar.get(Calendar.DATE);
    		int hour = calendar.get(Calendar.HOUR_OF_DAY);
    		int minute = calendar.get(Calendar.MINUTE);
    		int second = calendar.get(Calendar.SECOND);
    		String time = hour + "时" + minute + "分" + second + "秒";
    		System.out.println("北京时间:" + year + "年" + month + "月" + date + "日" + time + ",执行方法\"" + method.getName() + "\"");
    	}
    
    	public void after(Object object) {
    		System.out.println("执行结果:" + object);
    	}
    }

    至此,动态代理所需要的类就算创建完成了,接下来创建一个Client充当客户端来测试一下。

    import java.lang.reflect.Proxy;
    
    public class MainClass {
    	public static void main(String[] args) {
    		// 此处来创建了两个动态代理类对象...
    		UserDao userDao = new ImpUserDao();
    		DataBaseLogHandler userHandler = new DataBaseLogHandler(userDao);
    		DocumentDao doucumentDao = new ImpDocumentDao();
    		DataBaseLogHandler documentHandler = new DataBaseLogHandler(doucumentDao);
    		UserDao userProxy = (UserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(),
    				new Class[] { UserDao.class }, userHandler);
    		DocumentDao documentProxy = (DocumentDao) Proxy.newProxyInstance(DocumentDao.class.getClassLoader(),
    				new Class[] { DocumentDao.class }, documentHandler);
    		// 先输入一个不存在的用户Id登陆试试...
    		userProxy.login(20160718L);
    		documentProxy.add(new Document(30160711L, "转角遇见幸福"));
    		userProxy.logout();
    		// 再用一个真实用户Id登陆试试...
    		userProxy.login(20160708L);
    		documentProxy.add(new Document(30160711L, "转角遇见幸福"));
    		documentProxy.add(new Document(30160711L, "转角遇见幸福"));
    		userProxy.logout();
    	}
    }

    运行程序打印结果如下: 

    北京时间:2016年6月11日19时33分46秒,执行方法"login"
    执行结果:登陆失败,ID为"20160718"的用户不存在!
    北京时间:2016年6月11日19时33分46秒,执行方法"add"
    执行结果:保存失败,未获取到登陆信息!
    北京时间:2016年6月11日19时33分46秒,执行方法"logout"
    执行结果:退出登陆失败,当前无登陆用户!
    **********************************
    
    北京时间:2016年6月11日19时33分46秒,执行方法"login"
    执行结果:用户[燕凌娇]登陆成功...
    北京时间:2016年6月11日19时33分46秒,执行方法"add"
    执行结果:添加文档《转角遇见幸福》成功...
    北京时间:2016年6月11日19时33分46秒,执行方法"add"
    执行结果:添加文档《转角遇见幸福》失败,文档已存在!
    北京时间:2016年6月11日19时33分46秒,执行方法"logout"
    执行结果:用户[燕凌娇]退出登陆成功...
    **********************************
    

    从以上程序的最终运行结果可以看出:通过使用JDK自带的动态代理,我们同时实现了对ImpUserDao和ImpDocumentDao两个真实主题类的统一代理和集中控制。至于该动态代理类是如何被创建的?将在下一篇文章详细讨论,接下来我们先看看如何使用CGLIB实现动态代理。  

    三、使用CGLIB实现动态代理

    生成动态代理类的方法很多,如上例中JDK自带的动态代理、CGLIB、Javassist 或者 ASM 库。JDK 的动态代理使用简单,它内置在 JDK 中,因此不需要引入第三方 Jar 包,但相对功能比较弱。CGLIB 和 Javassist 都是高级的字节码生成库,总体性能比 JDK 自带的动态代理好,而且功能十分强大。ASM 是低级的字节码生成工具,使用 ASM 已经近乎于在使用 Java bytecode 编程,对开发人员要求最高,当然,也是性能最好的一种动态代理生成工具。但 ASM 的使用很繁琐,而且性能也没有数量级的提升,与 CGLIB 等高级字节码生成工具相比,ASM 程序的维护性较差,如果不是在对性能有苛刻要求的场合,还是推荐 CGLIB 或者 Javassist。

    接下来我们继续用上面的例子来体验一下如何使用CGLIB实现动态代理。

    首先,使用CGLIB来实现动态代理需引入“asm.jar”(CGLIB的底层是使用ASM实现的)和“cglib.jar”两个第三方jar包,引入两个jar包时需注意其版本,若版本有冲突会出现以下异常:Exception in thread "main" java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

    接下来开始写代码,延用上例中的:User类、Document类、DataBase类、两个抽象主题接口UserDao和DocumentDao、两个真实主题角色类ImpUserDao和ImpDocumentDao,这几个类无需做任何修改,此处不再重复贴出。

    去掉上例中的 DataBaseLogHandler 类,新增一个 CglibProxy 类,该类需实现CGLIB的 MethodInterceptor(方法拦截) 接口。 

    import java.lang.reflect.Method;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class CglibProxy implements MethodInterceptor {
    	private Calendar calendar;
    
    	/**
    	 * 创建动态代理类对象
    	 *
    	 * @param clazz
    	 *            需要创建子类代理的父类的类型
    	 * 
    	 * @return
    	 */
    	public Object getProxyInstance(Class<?> clazz) {
    		Enhancer enhancer = new Enhancer();
    		// 设置要创建的动态代理类的父类
    		enhancer.setSuperclass(clazz);
    		// 设置回调的对象,此句会导致调用动态代理类对象的方法会被指派到CglibProxy对象的intercept()方法
    		enhancer.setCallback(this);
    		// 通过字节码技术动态创建动态代理类实例
    		return enhancer.create();
    	}
    
    	@Override
    	// 回调方法
    	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    		before(method);
    		// 通过动态子类代理实例调用父类的方法
    		Object result = proxy.invokeSuper(obj, args);
    		after(result);
    		if (method.getName().equalsIgnoreCase("logout")) {
    			System.out.println("**********************************");
    			System.out.println("");
    		}
    		return result;
    	}
    
    	public void before(Method method) {
    		calendar = new GregorianCalendar();
    		int year = calendar.get(Calendar.YEAR);
    		int month = calendar.get(Calendar.MONTH);
    		int date = calendar.get(Calendar.DATE);
    		int hour = calendar.get(Calendar.HOUR_OF_DAY);
    		int minute = calendar.get(Calendar.MINUTE);
    		int second = calendar.get(Calendar.SECOND);
    		String time = hour + "时" + minute + "分" + second + "秒";
    		System.out
    				.println("北京时间:" + year + "年" + month + "月" + date + "日" + time + ",执行方法\"" + method.getName() + "\"");
    	}
    
    	public void after(Object object) {
    		System.out.println("执行结果:" + object);
    	}
    }

    对客户端进行相应修改,如下。 

    public class MainClass {
    	public static void main(String[] args) {
    		// 创建一个CglibProxy代理类对象,用来创建子类代理实例
    		CglibProxy cglib = new CglibProxy();
    		// 为ImpUserDao类添加一个动态代理类对象,即子类代理对象
    		UserDao userProxy = (UserDao) cglib.getProxyInstance(ImpUserDao.class);
    		// 为ImpDocumentDao类添加一个动态代理类对象,即子类代理对象
    		DocumentDao documentProxy = (DocumentDao) cglib.getProxyInstance(ImpDocumentDao.class);
    		// 先输入一个不存在的用户Id登陆试试...
    		userProxy.login(20160718L);
    		documentProxy.add(new Document(30160711L, "转角遇见幸福"));
    		userProxy.logout();
    		// 再用一个真实用户Id登陆试试...
    		userProxy.login(20160708L);
    		documentProxy.add(new Document(30160711L, "转角遇见幸福"));
    		documentProxy.add(new Document(30160711L, "转角遇见幸福"));
    		userProxy.logout();
    	}
    }

    运行程序结果打印如下,与之前使用JDK自带动态代理程序运行结果完全相同: 

    北京时间:2016年6月12日20时22分35秒,执行方法"login"
    执行结果:登陆失败,ID为"20160718"的用户不存在!
    北京时间:2016年6月12日20时22分35秒,执行方法"add"
    执行结果:保存失败,未获取到登陆信息!
    北京时间:2016年6月12日20时22分35秒,执行方法"logout"
    执行结果:退出登陆失败,当前无登陆用户!
    **********************************
    北京时间:2016年6月12日20时22分35秒,执行方法"login"
    执行结果:用户[燕凌娇]登陆成功...
    北京时间:2016年6月12日20时22分35秒,执行方法"add"
    执行结果:添加文档《转角遇见幸福》成功...
    北京时间:2016年6月12日20时22分35秒,执行方法"add"
    执行结果:添加文档《转角遇见幸福》失败,文档已存在!
    北京时间:2016年6月12日20时22分35秒,执行方法"logout"
    执行结果:用户[燕凌娇]退出登陆成功...
    **********************************

    PS:CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib采用动态创建子类的方法来对被代理的父类的功能进行增强和代理,所以,无法对被声明为final的类或方法进行代理。  

    四、动态代理模式的特点

    动态代理类使用字节码动态生成加载技术,在运行时生成并加载代理类。与静态代理相比,动态代理具有以下优点: 

    -无需单独为每一个接口添加一个代理类,使用动态代理可以一次性为多个接口实现代理。
    -无需逐个为接口中的所有方法添加实现,使用动态代理可以一次性为多个接口中的所有方法实现代理,在接口方法数量比较多的时候,可以避免出现大量的重复代码。

    动态代理的缺点:
               目前,JDK中提供的动态代理只能对接口实现代理,无法代理未实现接口的类。如果需要动态代理未实现接口的类,必须借助第三方工具,如:CGLib(Code Generation Library)等。

    参考文章

    《java的动态代理机制详解》

    《代理模式原理及实例讲解》

    《代理模式详解包含原理详解》

    《Java动态代理的实现》

    《JAVA学习篇--静态代理VS动态代理 》

    《深入理解Java Proxy机制》

    展开全文
  • Java模式(带书签)

    2019-01-11 17:01:02
    本书分为55章,第一个章节讲解一个编编程模式,说明此模式的用意、结构,以及这一模式适合于什么样的... 本书适合于Java程序员、架构设计师及设计模式爱好者,是一本实用的设计原则和设计模式的自学教材和使用手册
  • 2020年最新Java面试题整理,全网最全一份,包含各个技术栈,Java基础,Java集合,多线程,...MySQL,Nginx,rabbitmq,Redis,Tomcat,zookeeper,设计模式,数据结构,算法,分布式,限流,降级,cap原理等等知识点
  • java设计模式类书籍排行榜

    千次阅读 2010-07-19 10:59:52
    十本最经典的java设计模式类书籍推荐  No1: Java与模式(含盘)  作者:阎宏 编著 网上购买价格:¥65.20 去当当购买 书籍介绍:包括Java的芯片技术、Java的编译技术、Java的数据库连接技术、基于Java的信息...
  • Java设计模式-

    2012-07-30 13:47:34
    模式 java GOF 设计 疯狂 java大全 疯狂手册 java面试大全
  • 几个常用API,包括javaAPI规范、MySQL中文参考手册、W3CSchool、Http1.1,作为学习工具,可以很方便的查询java常用接口、类方法属性,mysql操作方法等,都是自己搜集的

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,674
精华内容 15,869
关键字:

java设计模式手册

java 订阅