Spring学习的第一天,分享下总结的笔记。
Spring入门Ioc以及DI
1、Spring的概述(了解)
1.1 Spring是什么
Spring是分层的Java SE/EE应用 full-stack轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。
1.2 Spring的发展历程
1997年IBM提出了EJB的思想
1998年,SUN制定开发标准规范EJB1.0
1999年,EJB1.1发布
2001年,EJB2.0发布
2003年,EJB2.1发布
2006年,EJB3.0发布
Rod Johnson(spring之父)
Expert One-to-One J2EE Design and Development(2002)
阐述了J2EE使用EJB开发设计的优点及解决方案
Expert One-to-One J2EE Development without EJB(2004)
阐述了J2EE开发不使用EJB的解决方式(Spring雏形)
1.3 Spring的优势
方便解耦,简化开发
通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
AOP编程的支持
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
降低JavaEE API的使用难度
Spring对JavaEE API(如JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。
Java源码是经典学习范例
Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。它的源代码无意是Java技术的最佳实践的范例。
1.4Spring的体系结构
2、程序的耦合(理解)
-
耦合:程序间的依赖关系
包括:
-
类之间的依赖
- 方法间的依赖
-
-
解耦:降低程序间的依赖关系
-
实际开发中:
应该做到:编译期不依赖,运行时才依赖 -
解耦思路:
第一步:使用反射来创建对象,而避免使用new关键字
第二步:通过读取配置文件来获取要创建的对象全限定名
3、核心容器的两个接口(掌握)
BeanFactory:
- BeanFactory才是Spring容器的顶层接口
ApplicationContext
- Application是BeanFactory的子接口
BeanFactory和Application的区别:
创建对象的时间点不一样。
ApplicationContext: 在构建核心容器时,创建对象采取的策略是立即加载的方式。也就是说,一读取完配置文件马上就创建配置文件中配置的对象。
BeanFactory:在构建核心容器时,创建对象采取的策略是延迟加载的方式。也即是说,什么时候使用,什么时候创建。
Spring对bean的管理细节
-
创建bean的三种方式
-
方式一:使用默认的无参构造函数创建。
<bean id="accountService" class="com.yang.service.impl.AccountServiceImpl"/>
-
方式二:使用工厂类的实例方法
<!-- 此种方式是: 先把工厂的创建交给spring来管理。 然后在使用工厂的bean来调用里面的方法 factory-bean属性:用于指定实例工厂bean的id。 factory-method属性:用于指定实例工厂中创建对象的方法。 --> <bean id="instancFactory" class="com.yang.factory.InstanceFactory"></bean> <bean id="accountService" factory-bean="instanceFactory" factory-method="工厂类实例方法的方法名"> </bean>
-
方式三:使用工厂类的静态方法
<!-- 此种方式是: 使用StaticFactory类中的静态方法createAccountService创建对象,并存入spring容器 id属性:指定bean的id,用于从容器中获取 class属性:指定静态工厂的全限定类名 factory-method属性:指定生产对象的静态方法 --> <bean id="accountService" class="com.yang.factory.StaticFactory" factory-method="createAccountService"></bean>
-
-
bean对象的作用范围
scope 属性指定bean的作用范围
singleton:默认值,单例的
prototype: 多例的
request: WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中
session: WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中
global session :WEB项目中,应用在集群中环境中就是 全局session,如果没有集群环境就相当于是 session
附加两个属性:
init-method:指定类中的初始化方法名称。
destroy-method:指定类中销毁方法名称。
-
bean对象的生命周期
单例对象 scope=“singleton”
一个应用只有一个对象的实例。他的作用范围就是整个应用
生命周期:
对象出生:当应用加载,容器创建时,对象就被创建
对象活着:只要容器在,对象一直活着
对象销毁:当应用卸载,容器销毁,对象就被销毁了
多例对象 scope="prototype"
每次访问对象,都会重新创建对象实例
生命周期:
对象出生:当使用对象时,创建新的对象实例
对象活着:只要对象在使用中,就一直活着
对象销毁:当对象长时间不用时,就会被java垃圾回收器回收了
4、依赖注入(掌握)
-
什么是依赖注入
依赖注入是Ioc的具体实现。Ioc的作用只是说降低了程序间的依赖关系,但是依赖还是存在的,当前类需要用到其他类的对象,由Spring为我们提供,我们只需要在配置文件中说明,这种依赖关系的维护就是依赖注入。
-
依赖注入的三种方式
-
方式一:使用构造函数提供
使用的标签:constructor-arg
标签出现的位置:bean标签的内部
标签中的属性
type: 用于指定要注入数据的数据类型,该数据类型也就是构造函数中某个或者是某些参数的类型。
index: 用于指定要注入的数据给构造函数中指定索位置的参数赋值。索引位置是从0开始。
name: 用于指定给构造函数中指定名称的参数赋值。 (常用)
=以上三个用于指定给构造函数中的哪个参数赋值=
value: 用于提供基本类型和String类型的数据。
ref: 用于指定其他的bean类型数据。(也就是引用类型的,对象)
优点:
在获取bean对象时,所需要的依赖,都已经提供好了。
弊端:
改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
-
方式二:使用set方法提供 (常用的方式)
使用的标签:property
标签出现的位置:bean标签内部
标签的属性:
name: 指定注入时调用的set方法的名称
ref: 用于指定其他的bean类型数据。也就是spring的Ioc容器中出现的bean对象
value: 用于提供基本类型和String类型的数据。
优势:在创建对象时没有明确的限制,可以使用默认的无参构造函数。
-
方式三:使用注解提供
-
-
能注入的数据格式
- 基本数据类型和String类型 —value
- 其他bean类型,也就是Spring的Ioc核心容器中的bean。—ref
- 复杂类型/集合类型
复杂类型的注入\集合类型的注入:
<!--给数组注入数据--> <property name="myArr"> <array> <value>AAA</value> <value>BBB</value> </array> </property>
<!--给list集合注入数据--> <property name="mylist"> <list> <value>AAA</value> <value>BBB</value> </list> </property>
<!--给set集合注入数据--> <property name="mySet"> <set> <value>AAA</value> <value>bbb</value> </set> </property>
<!--给map集合注入数据--> <property name="myMap"> <map> <entry key="k1" value="aaaa"></entry> <entry key="k2"> <value>bbbb</value> </entry> </map> </property>
``````<!--给property集合注入数据--> <property name="myProps"> <props> <prop key="k1"> aaaa </prop> <prop key="k2"> bbb </prop> </props> </property>
<!--给property集合注入数据--> <property name="myProps"> <props> <prop key="k1"> aaaa </prop> <prop key="k2"> bbb </prop> </props> </property>