文章目录
- 1.Spring的简介
- 2.Spring的起源与发展
- 3.Spring的核心体系介绍
- 4.Spring框架的特点总结
- 5.xml定义bean的相关属性
- 1、class属性、id属性、name属性
- 2、作用域属性
- 3、初始化方法和销毁方法
1.Spring的简介
Spring的英文翻译为春天,可以说是给Java程序员带来了春天,因为它极大的简化了开发。我得出一个公式:Spring = 春天 = Java程序员的春天 = 简化开发。最后的简化开发正是Spring框架带来的最大好处。
Spring是一个开放源代码的设计层面框架,它是于2003 年兴起的一个轻量级的Java 开发框架。由Rod Johnson创建,其前身为Interface21框架,后改为了Spring并且正式发布。Spring是为了解决企业应用开发的复杂性而创建的。它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。Spring 的理念:不去重新发明轮子。其核心是控制反转(IOC)和面向切面(AOP)。
2.Spring的起源与发展
在2002年10月,由Rod Johnson 编著的书名为《Expert One-to-One J2EE Design and Development》一书中,对Java EE 系统框架臃肿、低效、脱离现实的种种现状提出了质疑,并阐述了 J2EE 使用 EJB 开发设计的优点及解决方案,他提出了一个基于普通 Java 类和依赖注入的更简单的解决方案。然后以此书为指导思想,他编写了interface21框架,这是一个力图冲破J2EE传统开发的困境,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署的轻量级开发框架。Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。同年他又推出了一部堪称经典的力作《Expert one-on-one J2EE Development without EJB》,该书在Java世界掀起了轩然大波,不断改变着Java开发者程序设计和开发的思考方式。在该书中,作者根据自己多年丰富的实践经验,对EJB的各种笨重臃肿的结构进行了逐一的分析和否定,并分别以简洁实用的方式替换之。至此一战功成,Rod Johnson成为一个改变Java世界的大师级人物。值得注意的是,Rod Johnson是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
Spring框架自从发布以来,就得到快速发展,经过时代的验证,现在已经是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。从2004发布的第一个Spring版本,到现在已经更新到第五个Spring版本了,我们下面来看看各个版本的变化。
3.Spring的核心体系介绍
核心容器由 spring-core,spring-beans,spring-context,spring-context-support和spring-expression(SpEL,Spring 表达式语言,Spring Expression Language)等模块组成,它们的细节如下:
spring-core 模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。
spring-beans 模块提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。
context 模块建立在由 core和 beans 模块的基础上建立起来的,它以一种类似于 JNDI 注册的方式访问对象。Context 模块继承自 Bean 模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过 Servelet 容器)等功能。Context 模块也支持 Java EE 的功能,比如 EJB、JMX 和远程调用等。ApplicationContext 接口是 Context 模块的焦点。
spring-context-support 提供了对第三方集成到 Spring 上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。
spring-expression 模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是 JSP2.1 规范中定义的统一表达式语言的扩展,支持 set 和 get 属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从 Spring IoC 容器检索对象,还支持列表的投影、选择以及聚合等。
它们的完整依赖关系如下图所示:
4.Spring框架的特点总结
-
方便解耦,简化开发
Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理。
-
方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis 等)的直接支持。
-
降低 Java EE API 的使用难度
Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些 API 应用的难度大大降低。
-
方便程序的测试
Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序。
-
AOP 编程的支持
Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。
-
声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无须手动编程。
5.xml定义bean的相关属性
我们可以通过<bean>标签来配置spring 容器要管理的bean,它至少可以做到:
1、如何创建一个bean
2、bean的生命周期的详细信息
3、bean与bean之间的依赖关系
具体是如何做到的呢?下面有一张bean的属性表,每个属性对应的有不同的作用。
属性名 | 作用 |
---|---|
class | 这个属性是强制性的,并且指定用来创建 bean 的 bean 类 |
name/id | 这个属性指定唯一的 bean 标识符 |
scope | 指定由特定的 bean 定义创建的对象的作用域 |
constructor-arg | 用来注入依赖关系 |
properties | 用来注入依赖关系 |
autowiring mode | 用来注入依赖关系 |
lazy-initialization mode | 延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例 |
initialization 方法 | 在 bean 的所有必需的属性被容器设置之后,调用回调方法 |
destruction 方法 | 当包含该 bean 的容器被销毁时,使用回调方法 |
1、class属性、id属性、name属性
在xml文件中定义bean的时候,如果我不写id属性呢?我能否拿到class指定的类的对象呢?工厂是否还会帮我们创建呢?
答案是肯定的,只是此时我们要拿到该对象得通过class的值来获取,就比如下图:
但是,如果给了id,那么id属性就是作为唯一标识能获取该对象的标识。
在这里还会出现一个经典的报错场景,看下图:
了解了上图的信息后,我们需要思考;报的是bean定义的异常,那我能快速定位到xml文件,不会乱找;具体原因是说没有找到bean name,那我就应该去检查是不是bean定义时id的名字写错了,或者是代码中获取bean name与定义时的bean name不一致造成的。
通过阅读源码我们可以知道,它的本质也无非就是一个map在维护而已;key里面存放的就是对该类的描述;value里面存放的就是该类的对象
如果id和name都写上了的话,那么name属性的值会放在aliasMap里面维护。这就意味着通过name里面配置的别名也是可以获取到该bean的对象的。如图所示(也是在beanFactory下面):
2、作用域属性
通过scope属性来制定bean的作用域,它的取值有以下几个:
什么意思呢?意思就是prototy=“上图表五个中的其中一个”,示例
<!--给Student bean设置为原型模式,默认情况下是单例模式-->
<bean id="student" class="com.frank.Student" scope="prototype"></bean>
上面图表的后面三个属性值需要在mvc环境下才有,在纯spring-context依赖包的环境下只有前面两个,即singleton和prototype。
接下来,我们写点代码来看看这个singleton和prototype的区别。
创建好一个简单的maven工程后、
第一步:引入spring-context的jar包
第二步:编写bean.xml文件
<!-- Student类交给了spring管理,指定scope属性的值是singleton-->
<bean id="student" class="com.frank.Student" scope="singleton"></bean>
第三步:编写测试代码
// 1、首先要创建一个spring容器对象ApplicationContext application = new ClassPathXmlApplicationContext("bean.xml");// 2、通过容器对象调用getbean方法获取自己指定的对象Student stu1 = (Student) application.getBean("student");Student stu2 = (Student) application.getBean("student");Student stu3 = (Student) application.getBean("student");System.out.println(stu1);System.out.println(stu2);System.out.println(stu3);
运行结果:
但是如果我们把xml文件中bean标签里面的scope属性的值设置成prototype的话,那打印出来的结果就不一样了
<bean id="student" class="com.frank.Student" scope="prototype"></bean>
控制台打印的结果如下图:
3、初始化方法和销毁方法
面试题:如果我在对象创建完毕之后想做一些操作有几种方法,分别是什么?
至少是两种,第一种配置init-method属性;第二种实现InitializingBean接口,重写afterPropertiesSet()方法。