【重写SpringFramework】从零开始构建Spring框架:序言

spring源码解析spring-core之order排序 1.排序说明 spring在执行很多逻辑时都需要对bean实例集合进行排序,根据指定的优先级执行逻辑,spring内排序有关的有以下类 org.springframework.core.Ordered:用于定义指定实例order值得接口 org.springframework.core.PriorityOrdered:用于定义指定实例order值,且优先级高于Ordered接口 org.springframework.core.OrderComparator:支持Or... 阅读详情

1. 概述

在如今的 Java 后端开发中,引入几个依赖,添加几个注解,一个 web 应用就能启动起来。但我们能说开发者真的掌握相关技术了吗?高度封装的框架有利有弊,一方面提高了开发的效率,另一方面屏蔽了大量的实现细节,开发者只知其然而不知其所以然。对于开发人员来说,框架就是产品,提供的是成熟的服务。一般说掌握了某某框架,只是会使用而已,并不代表了解其原理。

要想更深入地理解框架,就需要阅读源码,这是横亘在每个开发者面前的大山。只有跨过了这道坎,编程水平会得到长足的进步,技术视野也会变得更加广阔。所谓他山之石,可以攻玉。通过对优秀框架的研究,掌握高明的设计理念和编程技巧,对于自身技术能力的提升大有裨益。

Spring 框架作为 Java 语言最流行最重要的开源框架,对于开发者来说不仅是使用工具,也是学习对象。我们将通过造轮子的方式重新构建整个框架,全面而深入地理解 Spring 框架的核心理念以及主体流程。

2. 面临的问题

2.1 内容庞杂

阅读源码的第一个问题是面对庞杂的体系,无处下手。即使阅读过一些书籍和文章,研究问题时往往也是一叶障目,不见泰山。这一现象产生的原因是缺乏系统化、模块化的思维方式,不能从全局视角进行整体把握。

目前市面上充斥着关于 Spring 框架的书籍和文章,往往有深度的无广度,有广度的无深度。一部分号称面面俱到,实际上蜻蜓点水,没有触及问题的核心。另外一部分对某些问题有比较深入的研究,但缺乏横向的联系,形成了一个个信息孤岛。要知道一个严密的系统是环环相扣的,仅对个别问题的研究并不能使我们认识到庐山真面目。

2.2 细节地狱

在阅读源码时,面对某一个功能,很容易陷入分支流程的无尽迷宫,以及异常繁琐的细节实现。我们将这种困境称为细节地狱(particulars hell),这种情况应当设法避免,应对的方法包括两个方面。

首先需要对功能进行划分,将一个大问题分解成若干个小问题。每个小问题都只关注一个方面,把代码量控制在一定的范围内。其次,阅读源码并不意味着一定要把所有的细节搞清楚,关键是掌握一个度。比如 JDK 原生的 API 会使用就足够了,当然对于一些重要的部分掌握其原理更好。Spring 核心包与 JDK 类似,提供了一些基础功能。因此我们并不打算深究其实现细节,直接引入 Spring 核心包作为整个项目的基石。

2.3 代码瘦身

Spring 框架演变至今,已经从一个功能单一的框架发展到了一个庞大的生态。即便仅考虑微服务体系的技术栈,也包括了几十个模块。对模块的选择是第一步,具体内容见下文的学习目标。仅对模块进行精简还是不够,代码量依然很大。虽然是造轮子,但并不是一比一复制,这样做既无可能也无必要。因此我们需要对代码进行精简,在这一过程中需要遵循一定的原则,要做到涵盖核心功能,确保主体流程的完整。

在当今的社会实践中,二八原则作为一项重要理论指导生产生活,其基本表述为少数实体占据多数资源。同样地,二八原则也适用于软件领域。对于一个框架来说,核心代码只占两成,另外八成是为了处理特殊情况,以保证代码的健壮性和扩展性。如果贪多求全,代码量会急剧增长,想独立完成 Spring 框架的重建几乎是不可能的。鉴于此,我们在代码层面上会进行一定的精简,但也不是那种浮于表面的 demo。我们关注的是 Spring 框架的核心流程,用尽可能少的代码来实现功能。

3. 学习目标

3.1 总体规划

本教程的学习计划分为三个阶段,首先是 Spring Framework,构建一个传统的 web 应用。其次,在 Spring Framework 的基础上,结合嵌入式 servlet 容器,构建 Spring Boot 应用。第三,以 Spring Boot 为基础,实现分布式的微服务体系。三个阶段环环相扣,通过逐步学习,对 Spring 框架的核心功能有全面而深入的理解。

图片

第一阶段的目标是构建一个传统 web 应用,将项目打包成一个 war 包,然后置于 servlet 容器(比如 Tomcat)的工作目录下。当 servlet 容器启动时,运行 web 应用。本阶段我们将实现 Spring Framework 的六个模块,包括 beans、aop、context、tx、web、webmvc 等。

第二阶段的目标是构建一个 Spring Boot 应用,最大的特点是将 servlet 容器嵌入到 web 应用中,实现开箱即用、约定大于配置等特性。本阶段我们将实现 Spring Boot 的四个模块,包括 tomcat-embed、mybatis、boot、boot-autoconfigure 等。其中 tomcat-embed 是嵌入式 servlet 容器,mybatis 是流行的 ORM 框架。它们都是第三方框架,属于选学部分。

第三阶段的目标是构建一组基于 Spring Boot 应用的微服务体系,包括注册中心、网关服务、业务服务(business service)等经典角色,实现服务治理、负载均衡、断路保护、高可用等分布式环境下的功能。本阶段我们将实现 Spring Cloud 的五大组件,包括 Eureka、Ribbon、Hystrix、Feign、Zuul 等,构建一个完整的微服务体系。

3.2 最终目标

本教程的最终目标是构建一个微服务体系,包括注册中心、网关服务,以及两个业务服务,即会员服务和订单服务。进一步,我们可以构建多组微服务,各组之间通过注册中心进行通信,从而形成高可用的分布式系统。

图片

对于一个微服务应用来说,需要引入若干依赖。以下是本教程所涉及的模块,按照三个阶段进行分组。其中,绿色标识属于 Spring Framework 的相关依赖,蓝色标识为 Spring Boot 的相关依赖,红色标识为 Spring Cloud 的相关依赖。

图片

在项目构建方面,我们严格按照 Spring Cloud 的标准方式来构建。包括使用 starter 引入依赖包、配置文件、声明注解来启动服务等。以网关服务为例进行说明,以下是 pom.xml 引入的依赖项:

图片

yaml 的配置包括服务名、端口号、与注册中心的通信、路由规则等,与 Zuul 服务的配置完全一致。

图片

应用主类声明了 @SpringBootApplication 和 @EnableZuulProxy 注解,并以 Spring Boot 应用的方式启动。

图片

在 IDE 中启动四个微服务应用,控制台打印启动日志,如下所示。

图片

3.3 本阶段目标

在第一阶段,我们的目标是实现 Spring Framework 六个模块,各模块之间的依赖关系如下所示。首先,我们需要依赖 Spring 核心包,这是唯一引入的 Spring 原生包。然后是 beans 和 aop 模块,它们提供核心的 IOC 和 AOP 功能。接下来是 context 模块,作为门面与用户(包括其他模块)打交道,比如大名鼎鼎的 ApplicationContext 就属于 context 模块。

接下来出现了两个分支,它们是 Spring Framework 的两个应用方向,通常会结合起来使用。在一个典型的 web 应用中,至少要引入 webmvc 和 jdbc 模块,然后通过依赖关系引入其他模块。

  • tx 和 jdbc 模块是为访问数据库提供服务的,由于 jdbc 模块的代码较少,我们将其归入了 tx 模块中。

  • web 模块提供了 web 应用的基础组件,比如 WebApplicationContext 表示运行在 web 环境中的 Spring 容器。理论上我们可以利用这些组件构建 web 应用,实际上很难直接使用。

  • webmvc 模块引入了 MVC 架构,极大地提高了 web 应用的开发效率。事实上,构建 web 应用可以选择其他 MVC 架构,比如以前比较流行的 Struts2 框架。

图片

4. 本教程的特点

4.1 分层方法论

前面分析了阅读源码时的种种困难,那么正确的做法是什么,我们针对高中低不同的层次总结了三条原则。

  • 在顶层设计方面,做到高屋建瓴,俯瞰全局。这一层次主要是抽象的理念上的认识,比如 Spring Framework、Spring Boot、Spring Cloud 三者之间的关系是如何组织的,各模块的定位以及模块之间的依赖是如何处理的。

  • 在中间架构方面,做到提纲挈领,纲举目张。对于一个业务范畴,比如 IOC 和 AOP 机制、数据库事务等,它们的主体结构是如何建立的,可以分解为多少个具体的功能,其中用到了哪些编程思想和设计模式。一个模块往往包含一个或几个业务范畴,抓住了这些关键节点,对于整个模块的理解会变得事半功倍。

  • 在底层实现方面,做到条分缕析,举一反三。我们需要了解具体的功能用到了哪些技术,这些技术的特点以及各自的适用情况。特别是很多功能之间有着清晰的演进脉络,比如一个功能看上去很复杂,但如果了解前置的技术,再来看该功能,大部分是对原有技术的整合,还有一部分新内容,总体而言更容易理解。

如果我们把 Spring 框架看作一个大型建筑,那么顶层设计就是项目蓝图,规划了建筑的形制与功能。中间架构是地基和框架,承载了整个建筑的主体结构。底层实现是砖石材料,填充完善细节部分。三者不可偏废,互相配合,最终造就了 Spring 这座宏伟的殿堂。

4.2 渐进式开发

本教程的出发点是从框架编写者的角度考虑问题,而不是从使用者的角度考虑问题。面向对象编程的核心是组织和调度,单独编写一个功能对开发者来说很简单,但要将若干个功能整合在一起,从而构成一个庞大的、严密的、完备的体系,就必须遵循一定的规律。因此我们采取的是渐进式开发,先从最基础的功能做起,从简单到复杂,从单一功能到统一的有机的整体结构。我们将按照模块的依赖关系进行讲解,先介绍底层模块,然后是上层模块,以此类推。大多数情况下,我们会遵循这一原则,当然也有例外,届时会进行说明。

举个例子,在介绍 IOC 容器时,通常是把 BeanFactory 与 ApplicationContext 结合起来一起讲。实际上,前者属于 beans 模块,后者属于 context 模块。我们会先介绍 BeanFactory 的基本功能,再介绍 ApplicationContext 的作用,至于两者之间的区别和联系,这又牵扯到 beans 和 context 模块各自的定位,这些问题将在学习的过程中予以解答。

4.3 测试用例

本教程提供了丰富的测试内容,每一节都会设计若干测试用例,使得读者在读完本节后,知道该做什么。而不是像某些纯源码读物,看了之后云山雾里,不知所云。出于控制代码量的考虑,测试用例仅覆盖重点介绍的核心功能。此外,还有一些常用但比较次要的功能,该部分的实现和测试交由读者来完成,进一步巩固学习效果。

5. 版本选择

为了方便读者对照源码,我们在版本的选择上进行一定的考量。Spring Cloud 的版本选择 Edgware 或 Dalston,对应的 Spring Boot 版本是 1.5.x。Spring Boot 的版本选择 1.5.22.RELEASE,这是 1.5.x 的最后一个发布版。与之对应的是 Spring Framework 的版本是 4.3.25.RELEASE,这也是 Spring4 的最后一个发布版。

图片

为什么选择低版本的 Spring Cloud?一开始 Spring Cloud 是对 Netflix 的微服务组件进行封装,后来 Netflix 停止了相关组件的开源。如果使用高版本的 Spring Cloud,由于 Netflix 停止了对 Zuul、Feign 等组件的支持,Spring Cloud 不得不使用 Gateway 和 OpenFeign 来代替。此外,Eureka 也可以使用 Nacos、Appllo 等注册中心组件来替代。我们来分析一下这些组件的影响:

  • Gateway 使用 Webflux 代替了 SpringMVC 框架,使用了响应式编程的代码风格,增加了理解的难度。更重要的是,嵌入式的 Tomcat 服务替换成了 Netty 框架。而 Spring Boot 使用 Tomcat 作为 servlet 容器,我们不希望增加学习的成本,因此选择 Zuul 作为网关服务。

  • OpenFeign 大体上继承了原本 Feign 组件的逻辑,区别不大。

  • Eureka 虽然也有替代的 Nacos 等注册中心,但它们毕竟是第三方框架,不便研究源码。

此外,Spring Framework 版本的选择也有一定的考量。Spring5 相比 Spring4 来说,增加了很多新东西。比如对 Koltin 语言的支持,很多地方的代码使用函数式编程的风格重写,增加了阅读源码的难度。因此,选择 Spring4 的最后一个发行版,既保证了稳定性,又与 Spring Boot 版本保持一致,可谓一举两得。

总的来说,我们的目标从整体层面了解微服务的治理,为了分析核心组件的原理,因此选择较低版本的 Spring Cloud。至于 Spring Framework 和 Spring Boot 则选择了大版本的最后一个发布版,我们认为这一版本的完成度和稳定性是很高的,可以作为源码的参考依据。

6. 结语

庖丁解牛是《庄子•养生主》中记载的一则脍炙人口的故事。庖丁为文惠君表演杀牛的技艺,文惠君对庖丁高超的技巧叹为观止,并询问是如何做到的。庖丁解释说自己一开始杀牛时,看到的只是眼前的牛。三年之后,就看不到全牛了,是因为自己做到了以神遇而不以目视,官知止而神欲行。这是说掌握了事物的运行规律,就能做到胸有成竹,随心所欲。具体的做法是彼节者有间,而刀刃者无厚。以无厚入有间,恢恢乎其于游刃必有余地矣。这是说牛的骨骼肌肉是有间隙的,但刀刃很薄几乎没有厚度。把没有厚度的刀刃放到骨肉的间隙中,自然就游刃有余了。

文惠君从庖丁解牛的过程中领悟了养生的道理,同样地,我们也可以用来研究编程的问题。Spring 框架对我们来说是一个庞然大物,但再大的系统也是有间隙的,是由一个个基本单元组成的。我们只要合理运用编程思想、设计模式等工具,对复杂系统进行分解,把每一个基本单元搞清楚,也能达到「以无厚入有间,游刃有余」的境界。

Spring框架中的@Order注解详解及应用实例 Order注解位于包中,它可以用来指定Bean的加载顺序。如果没有指定@Order,Spring默认的顺序是。 阅读详情

相关推荐

MLX90640 热成像 STM32

MLX90640 热成像

zhaocundang's blog 5008

Spring注解--@Order--使用/实例

本文用示例介绍@Order(顺序)注解的用法。

IT利刃出鞘的博客 4996

R语言分段回归

1.利用虚拟变量进行线性回归 (MEdata.csv的数据来源:https://github.com/ChenQihome9/优快云-Data-Library/blob/master/MEdata.csv) 问题13:针对TAX~GDP,使用分段回归方法,找到其回归方程。编程,并根据程序结果叙述如下几方面问题:(1)分几段最佳?(不超过5段内)(2)分段位置定在哪儿最佳?(3)写出最佳方...

ChenQihome9的博客 1万+

@Order注解提供消费顺序

Order注解可以做到集合bean依赖注入的时候,定义集合内部Bean的加载顺序,因此在需要有序消费bean的时候,不需要再次排序,直接定义好Order注解得value值就好。 但是这个order值并不影响bean本身实例化的顺序,因为实例化的顺序取决于依赖关系。 @org.springframework.core.annotation.Order @RestController @RequestMapping(value = "/pc/api/...

大宇的博客,欢迎访问 6165

Innovus快捷键大全:从入门到精通的效率提升指南

本文是Innovus快捷键从入门到精通的效率提升指南,旨在帮助芯片后端设计工程师通过掌握核心快捷键,将重复性鼠标操作转化为高效的肌肉记忆,从而显著提升版图设计、编辑和分析的工作流速度。文章系统讲解了视图导航、对象选择编辑、流程管理等关键快捷键组合,并提供了个性化配置与实战策略,助力工程师突破效率瓶颈,实现人机合一的流畅设计体验。

silver的专栏 797

MCGS 昆仑通态触摸屏 modbus TCP 数据转发

MCGS触摸屏数据转发modbus TCP数据转发

m0_63451859的博客 2万+

Spring 5.3.27 CVE-2016-1000027 修复方案对比:AOP拦截 vs 源码重写 vs 升级Spring 6

本文深入分析了Spring 5.3.27中CVE-2016-1000027安全漏洞的三种修复方案:AOP拦截、源码重写和升级Spring 6。通过对比实施复杂度、兼容性、安全性等维度,为技术决策者提供最优选择建议,帮助企业有效应对这一高危反序列化漏洞。

dechen6073的博客 444

Coze实战:解锁多Bot协同与条件分支工作流的奥秘

本文详细介绍了在字节跳动Coze平台实现多Bot协同与条件分支工作流的方法。首先阐述了Coze平台的功能优势,包括丰富的插件、知识库和工作流功能。随后分步骤讲解了多Bot协同的实现:从准备工作、创建Bot到协同配置,并提供了电商客服的实例演示。在条件分支工作流部分,详细说明了条件节点的作用类型、条件设定方法以及具体配置操作,强调测试优化的重要性。最后通过电商平台综合案例,展示了多Bot协同与条件分支的实际应用效果,并针对常见问题提供解决方案。文章为开发者在Coze平台上构建智能应用提供了实用指导,有助于提升

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 451

【重写SpringFramework】声明式事务上:构建事务切面(chapter 4-5)

上一节介绍了编程式事务,我们发现,事务操作有两个特点。一是事务操作广泛地出现在应用程序中,二是事务操作的逻辑是有迹可循的,无非是对开启事务、回滚和提交这几个操作的组合使用。换句话说,事务操作是一种公共行为,可以从众多的业务代码中剥离出来,这是很典型的面向切面编程。因此,Spring 依托已有的 AOP 功能,提供了一套使用注解进行事务管理的解决方案,即声明式事务。声明式事务可以看做是面向切面编程的一个用例,在实际开发中得到了广泛地使用。

2401_89221445的博客 1049

【100%通过率】华为od机试C卷【出差 / 员工派遣】Java&Go 实现

某公司部门需要派遣员工去国外做项目。现在,代号为 x 的国家和代号为 y 的国家分别需要 cntx 名和 cnty 名员工部门每个员工有一个员工号 (1,2,3,......),工号连续,从 1开始。部长派遣员工的规则:

MISAYAONE的博客 2642

句向量(句嵌入)模型sent2vec的训练及应用

本文讨论NLP中的句向量模型(sent2vec),也就是将一个完整的句子映射成一个实数向量的技术。这方面已经发表的成果也是比较多的,本文中所涉及的技术主要源自NAACL 2018的一篇论文,其中提出的sent2vec模型可以理解为词嵌入技术中经典的CBOW方法的扩展,该所谓的扩展中一个重要改进就是引入了n-gram

白马负金羁 1万+

【重写SpringFramework】第二章aop模块:Spring Advice(chapter 2-2)

在只有抽象描述的情况下,Spring Advice完成了对AOP规范的初步实现。增强逻辑是变化的,调用时机是不变的,Spring 如何来降低系统耦合度?

Stimd的博客 1319

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【重写SpringFramework】第一章beans模块:FactoryBean(chapter 1-11)

BeanFactory和FactoryBean傻傻分不清楚。什么是IOC机制的反模式,为什么说编程是一门妥协的艺术?

Stimd的博客 1245

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【重写SpringFramework】ApplicationContext概述(chapter 3-1)

IOC 和 AOP 是 Spring 框架的两大核心机制,我们已经在 beans 和 aop 模块中有过详细论述了。尤其是 beans 模块,其基础性表现在各个分散的功能中,并不适宜直接被用户(开发者)使用。鉴于此,Spring 提供了 context 模块整合了 beans 和 aop 模块,不仅隐藏了底层的细节,还提供了一系列强大、易用的功能,对于用户(开发者)十分友好。在实际使用中,开发者在和 context 模块的 API 打交道,只有很少的操作可能会涉及到底层模块。

2301_78976656的博客 1117

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

【重写SpringFramework】第一章beans模块:本章小结(chapter 1-13)

温故而知新,停下来是为了更好的前进。对这一阶段的知识点进行梳理和总结,查漏补缺,力求做到心中有数。

Stimd的博客 1384

【重写SpringFramework】第二章aop模块:AOP代理上(chapter 2-4)

增强和切面功能的落脚点是对象的方法,因此需要将目标对象纳入到AOP的体系中,这一过程是通过代理模式完成的。

Stimd的博客 878

每周小记——Spring框架

本文解析了Spring框架的四大核心机制:工厂模式通过BeanFactory和ApplicationContext实现Bean生命周期管理,奠定IoC容器基础;控制反转与依赖注入将对象创建权移交容器,通过配置解耦组件,提升系统灵活性;面向切面编程基于代理模式(静态/JDK动态/CGLIB)实现横切关注点(如日志、事务)与业务逻辑分离,并总结了五种通知类型及其配置方法。文章系统阐述了Spring如何通过设计模式优化Java企业级开发,强化代码可维护性与模块化,凸显其在现代架构中的关键作用

weixin_57655687的博客 1553

【重写SpringFramework】第一章beans模块:类型转换(chapter 1-2)

千里之行,始于足下。第一行代码,从基础的类型转换功能开始,初步领略Spring框架是如何组织代码的。

Stimd的博客 1063

【重写SpringFramework】配置类概述(chapter 3-5)

在早期的 Spring 项目中,使用 XML 文件进行配置。如下所示,在配置文件中,使用bean标签注册组件,使用标签批量扫描组件,使用import标签引入其他的 XML 文件,使用标签加载配置文件,等等。此外,有的标签带有前缀,需要引入相应的名称空间,操作起来异常繁琐。鉴于此,Spring 提供了一套声明式的解决方案,以配置类为核心,为我们提供了更加方便快捷、灵活多样的配置应用的方式。xml代码解读复制代码。

2301_78976656的博客 1091

Spring Boot入门指南:快速构建Java Web应用

Spring Boot作为Java生态中的主流框架,通过约定优于配置的原则大幅简化了Spring应用的开发流程。其核心机制是自动配置,能够根据classpath依赖智能装配组件,开发者只需关注业务逻辑实现。技术实现上,Spring Boot整合了内嵌服务器、Starter依赖等模块,显著降低了从开发到部署的复杂度。在微服务架构和云原生场景中,Spring Boot因其轻量级特性和生产就绪功能(如健康检查、指标监控)成为首选框架。结合热词分析,本文特别详解了自动配置原理与REST API开发实践,帮助开发者快

weixin_34323858的博客 515

【重写SpringFramework】第二章aop模块:本章小结(chapter 2-8)

在 Spring 框架中,IOC 和 AOP 共同构成了整个体系的基础。第一章介绍了 IOC 机制,本章关注的是 AOP 功能。相对于 beans 模块而言,aop 模块的功能更加单一,因此从代码层面来说,aop 模块有一条非常清晰的主线,分为三个阶段。准备工作:对 AOP 规范进行分析,得到的结论是,要实现 AOP 功能需要满足三要素,即增强、切面和代理。主体部分:实现了 AOP 的三要素。首先是增强,对Advice接口进行扩展,主要关注方法的拦截和调用。然后是切面,通过Advisor。

CTZL123456的博客 972

Spring

Spring1.Spring是什么?有什么好处?2.IOC是什么?有什么好处?具体过程?3.DI是什么?4.IOC和DI的关系?5.bean标签的属性有哪些?6.IOC创建对象有哪几种方式?7.Spring是如何实现IOC的?也就是如何创建对象的? 1.Spring是什么?有什么好处? 概念: SPring是一个支持控制反转(IOC)和面向切面编程(AOP)的容器框架。 好处: 两降低>&...

weixin_43766298的博客 1万+

【重写SpringFramework】第一章beans模块:单例创建(chapter 1-5)

从手工作坊到自动化流水线,BeanFactory提高了创建对象的效率。工业化生产的特点是标准化,那么在代码中应该依据怎样的标准?

Stimd的博客 1105

【重写SpringFramework】第二章aop模块:自动代理上(chapter 2-6)

在前边几节内容中,我们介绍了 Spring AOP 的三大核心,增强、切面和代理,此时已经可以实现一个完整的 AOP 的功能。但仔细想一下,代理对象需要一个个去创建,显得异常繁琐,因此我们需要把创建代理对象的流程自动化。具体思路是,依托 Spring 容器强大的管理能力,在 Bean 创建流程中检查对象是否需要被代理,从而实现自动创建代理的功能。更为重要的是,通过自动代理组件将 AOP 机制与 Spring 容器联系起来,这意味着 Spring 框架的两大基石就此得以确立。

2301_78976656的博客 1112
上一篇: Spring基础-Spring和Spring框架组成
下一篇: VUE 组件化开发与组件思想入门篇
JavaASDN
博客等级 码龄2年 236粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值