Spring实战:
以前是学集成电路的,工作之后成了一枚java程序猿,记得第一次接触企业级应用开发,对于Spring容器、 bean、bean的装配、应用上下文、依赖注入、控制反转等等非常核心的概念经常是一脸懵逼的状态,最近看了Spring实战讲述的两个Spring核心技术,看的过程中其实还是懵逼的,不过重复看了几遍对概念理解了,之后发现以前总是困扰自己的问题已经不再是问题,所以写了这边文章讲一下自己对这些关键词的理解,一方面加深自己的理解,另一方面用一个通俗的大白话将自己的理解表述出来希望能帮到一些刚入行的同学,希望有所帮助。
了解某种技术之前首先要知道它为什么出现,它的出现是为了解决什么问题?-------Spring是为了解决企业级应用开发的复杂性即简化java开发而创建的。
Spring的核心是依赖注入(DI)和面向切面编程(AOP)。
任何一个有实际意义的应用,都会有多个类组成,这些类相互之间尽心协作来完成特定的业务逻辑。按照传统做法,每个对象本身负责管理与自身协作的对象的引用(即他所依赖的类的实例),这将导致类与类之间高度耦合和难以测试的代码,这种代码难以复用,难于理解,而且典型的会表现出打地鼠是的bug特性。但另一方面,一定程度上的耦合又是必须的。通过DI,对象以及对象之间的依赖关系完全交由第三方进行处理,对象无需自行创建或者管理他们之间的依赖关系(一般选择的做法是,如果类A需要依赖类B,一般将类B实现的接口定义为类A的属性,这样做的目的是,对象只是通过接口(而非具体的类实现)来标明依赖关系,那么这种依赖就能够在对象本身毫不知情的情况下,用不同的具体实现进行替换)。在基于Spring的应用中,Spring容器负责创建对象,装配对象、配置并管理他们的整个生命周期,从生存到死亡,常见的容器为应用上下文(Application Context)。
DI能够允许相互协作的软件组件保持松散耦合,而面向切面编程则允许你把遍布应用各处的功能分离出来形成可重用的组件。
①看书心得:
大概扫过一些主要内容之后,返回来看第一章,发现Spring可以和一个公司的进行类比,这个公司包含了所有的职能部门以及各种成熟的规章制度流程。开发过程可以理解为公司要开始进行运行一个业务,开发人员就是这个业务对应的唯一拍板领导,领导不必事无巨细,只需要定义业务运行中需要什么样的人才(bean)(这个过程可能也包含了人与人之间的协作,类比为你定义的类A依赖类B),具体的就可以交公司即Spring进行具体的管理,公司不能满足你的需求时,领导还可以找外包公司即集成第三方框架来完成任务。
开发人员--------领导,leader;
应用上下文------Spring容器的一种,负责bean的创建,装配,销毁等,类比为秘书或者总经理,assistant;
bean--------------领导定义的具备某种素质的员工,其实就是我们定义的类的实例,employee;
bean的装配-----Spring容器负责管理的,协调员工和员工之间的协作,类A依赖类B,秘书直接将符合条件的B类实例指派给A类实例,这个过程开发人并不需要关心如何实现,cooperation;
依赖注入---------就是bean装配的过程,即将类B的实例注入类A的过程。
首先对于DI,Spring中是通过容器(如bean工厂或者应用上下文,前者最简单,提供基本的DI支持,对大多数应用来说比较低级;后者基于beanFactory构建,并提供应用框架级别的服务,如从属性文件解析文本信息以及发布用用事件给感兴趣的事件监听者,比前者更受欢迎)管理bean的,包括bean的创建、生命周期、销毁等,应用上下文就可以类比为领导的秘书,开发人员是核心领导,每个bean就可以类比为公司中的螺丝钉员工,开发人员只需要定义需要的类以及类与类之间的依赖关系,接下来当应用启动后,首先加载应用上下文也就是公司会先派来一名秘书即Spring容器,然后秘书负责创建即招聘来领导需要的每个员工(bean初始化)以及协调员工之间的合作。所以要想实现依赖逐日的功能,就离不开容器,容器是Spring框架实现功能的核心,但是容器的实现有很多中方式,不唯一,常用的就是应用上下文;
当员工需要其他员工(Abean中注入beanB-bean的装配)的时候,秘书去按照领要求招聘来的所有员工中寻找有没有这种符合条件的员工,当有的时候直接将这个其他员工指派给前者,员工是不用关心他需要的其他员工如何被指派过来,这个过程就是装配bean的过程。开发人员(即领导)负责规划,即在程序中定义要招聘具备哪些素质的员工,以及他们之间如何协作(即告诉Spring bean之间的依赖关系),秘书(Spring容器)负责执行领导的命令,即按需求照招聘员工,将员工B指派给员工A。若公司里不存在符合条件的员工B就会抛出异常,秘书表示解决不了,需要领导上手修改代码解决问题;或者当有多个满足条件的员工B时,也会抛出异常,秘书表示解决不了,需要领导修改代码直到秘书可以唯一确定一个员工B。所有员工会一直被秘书代为管理,直到秘书被撤职;
而对于AOP,可以类比为公司的职能部门,如人力资源,法律、后勤等,公司给每个员工都需要发工资,这不是员工应该关心的工作方面的问题,所以公司将这个交给职能部门去解决,领导只要安排好工作,当到公司结算日期(切点),人力资源专员(切面,即POJO)就会开始结算需要结算工资的员工的工资并将工资发放给员工(结算和发放行为就是通知);
Spring还能通过使用模板消除重复的样式代码,比如集成持久化框架,这个可以类比为公司的一些审批流程化,例如员工请假,员工请假本来是需要首先填写假条,然后逐次找各级领导审批,审批完成之后在提交给相关部门进行备份入库等,其中有一步有问题整个流程都会问题,这样太麻烦了,所以公司将其流程化,员工只需要填写申请单,其他的重复流程(如后面的审批提交入库等)交给公司去做,员工只需要等待结果(类比为只需要在代码中实现必须的逻辑,其他后续的工作都交给Spring来做),这个过程就消除了重复的样板代码。
②以下是Spring实战原文讲述的Spring容器中的bean生命周期:
详细描述为:
1、Spring对bean进行实例化(即创建对象,对属性赋值,初始化方法等);
2、Spring将值和bean的引用注入到bean对应的属性中(bean的装配);
3、如果bean实现了BeanNameAware接口,Spring则将bean的ID传递给setBeanName()方法(可类比为给员工一个员工ID);
4、如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入(现在常用的就是应用上下文容器,Spring初始化容器来管理开发人员创建的bean);
5、如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用(即应用上下文实例)传入进来;
6、如果bean实现了BeanPostProcessor接口,Spring将调用他们的postProcessBeforeInitialization()方法(这个目前还不知道是为了干什么);
7、如果bean实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法,类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用;
8、如果bean实现了BeanPostProcessor接口,Spring将调用他们的postProcessAfterInitialization()方法(这个目前还不知道是为了干什么);
9、此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;
10、如果bean实现了DisposableBean接口,Spring将调用他的destroy()接口方法。同样地,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。
③Spring模块
Spring发布版本中包含了很多不同的模块,按照功能划分为6类
就总体而言,这些模块为企业级开发应用提供了所需的一切,但是你自己的应用是不用引入所有的模块,只需要根据自身的需求引入对应的功能,加入Spring不能满足需求时,你可以集成第三方框架和类库,来实现你要实现的功能。