概述:
Spring的概述、SpringIOC入门(XML)、Spring的Bean管理、Spring属性注入
Spring的IOC的注解方式、Spring的AOP开发(XML)
Spring的AOP的注解开发、Spring的声明式事务、JdbcTemplate。
SSH的整合、HibernateTemplate的使用、OpenSessionInViewFilter的使用。
1. Spring概述
轻量级的Java开源框架,与2003年兴起。Spring是一个分层的Java SE/EE一站式(FullStack)轻量级的开源框架。Spring:SE/EE开发的一站式框架。
-
一站式框架:有EE开发的每一层解决方案。
-
WEB层 :SpringMVC
-
Service层 :Spring的Bean管理,Spring声明式事务
-
DAO层 :Spring的Jdbc模板,Spring的ORM模块:hibernate,mybatis , jdbcTemplate
–> spring-data
-
-
它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
-
轻量级:与EJB对比,依赖资源少,销毁的资源少
-
Spring的核心:控制反转(IoC)和面向切面编程(AOP)
-
Spring的优势:
-
方便解耦,简化开发 (高内聚低耦合)
• Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理
• spring工厂是用于生成bean
-
AOP编程的支持
• Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
-
声明式事务的支持
• 只需要通过配置就可以完成对事务的管理,而无需手动编程
-
方便程序的测试
• Spring对Junit4支持,可以通过注解方便的测试Spring程序
-
方便集成各种优秀框架
• Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
-
降低JavaEE API的使用难度
• Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
-
-
Spring版本:3.x/4.x/5.x
2. 体系结构
- 下载使用:http://spring.io/
3. IOC:控制反转
Inversion of Control:将对象的创建权反转给(交给)Spring,Spring就是一个大的容器、大工厂。
3.1 构建步骤:
创建工程->导入JAR包(4核心+1个依赖)->配置文件后源码中使用
3.2 工程
-
docs :Spring的开发规范和API——doc下有pdf版本文档:spring开发规范
-
libs :Spring的开发的jar和源码
-
schema :Spring的配置文件的约束
3.3 为什么使用IOC
与开发中的设计模式有关:从传统的直接创建对象的模式,到“接口+实现类”的模式,再到简单工厂模式;主要是在一步步进行程序模块间的解耦问题,而Spring是目前最优秀的解耦方式组织成的框架。Spring就是一个自动化的大工厂。
解耦的主要作用:OCP原则——对源码修改的关闭、对扩展的开放。尤其在大型项目组织中见效。
3.4 示例
-
使用Spring来进行简单工厂的代替,通过配置文件,Spring能够解析XMl文件并使用底层的反射机制进行实例的生产。
-
Spring采用Schema形式的xml配置文件,一般开发中直接在SRC目录下,惯例命名为
applicationContext.xml
。基本的配置,命名空间等可以在spring解析目录下的\docs\spring-framework-reference\html\xsd-configuration.html
找到。<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置Bean --> <bean id="userDao" class="com.leehao.springlearning.spring1.UserDaoImpl"></bean> </beans> -------------------------------------------------------------------------------- public void demo1(){ //解析配置文件 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //直接获取bean UserDao userDao = applicationContext.getBean(UserDao.class); userDao.save(); }
3.5 IOC和DI
IOC就是把控制权交给spring,类的实例通过其去构造。而DI则是在IOC的条件前提下,Spring管理当前类时,可以把与之依赖的属性注入(设置)到当前对象中。
4. Spring的工厂类
Spring的两个工厂类BeanFactory和ApplicationContext,是两个不同的版本,ApplicationContext继承BeanFactory。
-
Bean加载的两种情形:
-
使用BeanFactory,慢加载过程;在第一次调用Bean时才会新建对象
-
使用ApplicationContext,加载完xml文件后,即刻初始化对象。
-
ApplicationContext有两个实现类
-
ClassPathXmlApplicationContext :加载类路径下src的配置文件
-
FileSystemXmlApplicationContext :加载文件系统下的配置文件
-
-
5. Spring 的配置
5.1 Bean配置
-
ID和Name:
-
id :使用了约束中的唯一约束。里面不能出现特殊字符的。
-
name :没有使用约束中的唯一约束(理论上可以出现重复的,但是实际开发不能出现的)。里面可以出现特殊字符。n Spring和Struts1框架整合的时候使用:<bean name="/user" class=""/>
-
-
生命周期:
-
init-method :Bean被初始化的时候执行的方法
-
destroy-method :Bean被销毁的时候执行的方法(Bean是单例创建的,关闭工厂的实例时会触发;多例时不会触发)
-
-
Bean的作用范围
- scope:Bean的作用范围,5个取值;
- singleton :默认的,Spring会采用单例模式创建这个对象。
- prototype :多例模式。(Struts2和Spring整合一定会用到)
- request :应用在web项目中,Spring创建这个类以后,将这个类存入到request范围中
- session :应用在web项目中,Spring创建这个类以后,将这个类存入到session范围中
- globalsession :应用在web项目中,必须在porlet环境下使用(如百度和百度地图的子网站等)。但是如果没有这种环境,相当于session。
- scope:Bean的作用范围,5个取值;
5.2 属性注入
-
使用构造方式的注入——xml
-
使用set方法的注入——xml
<bean id="car" class="com.leehao.springlearning.DI.Car" > <property name="name" value="BMW"></property> <property name="price"> <value>100000</value> </property> </bean> <bean id="user" class="com.leehao.springlearning.DI.User"> <constructor-arg name="name" value="真三"></constructor-arg> <constructor-arg name="car" ref="car"></constructor-arg> </bean>
-
使用带命名空间的方式注入——xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- 使用命名空间p --> <bean id="car2" class="com.leehao.springlearning.DI.Car" p:name="QQ" p:price="1000"/>
-
SpEL(Spring Expression Language)的方式注入:去除了value-ref,所有的属性全都使用name和value两个标签决定。在SpEL中,value的值使用
#{SpEl}
的方式复制,可以是常量、表达式、操作、Bean对象和其他对象等。<property name="" value="#{表达式}">-
#{123}、#{‘jack’} : 数字、字符串
-
#{beanId} :另一个bean引用
-
#{beanId.propName} :操作数据
-
#{beanId.toString()} :执行方法
-
#{T(类).字段|方法} :静态方法或字段
<!-- SpEL --> <bean id="car3" class="com.leehao.springlearning.DI.Car" > <property name="name" value="#{'TT'}"></property> <property name="price" value="#{200+300}"></property> </bean> <bean id="car4" class="com.leehao.springlearning.DI.Car"> <property name="name" value="#{user.name}"></property> </bean>
-
5.3 集合属性的注入
-
集合注入:在xml中的property加入子标签,可以注入set/list/map等集合属性
- property中普通数据标签<value>
- 引用数据标签<ref>
<!-- 集合类型的注入 --> <bean id="collectionBean" class="com.leehao.springlearning.DI.CollectionBean"> <!-- list和数组一样 --> <property name="stus"> <list> <value>张三</value> <value>李四</value> </list> </property> <property name="list"> <list> <value>AAAAA</value> <value>BBBBB</value> </list> </property> <property name="mySet"> <set> <value>你好</value> <value>当然</value> </set> </property> <property name="map"> <map> <entry key="aaa" value="888"/> <entry key="bbb" value="999"/> </map> </property> </bean>
5.4 Spring创建Bean的三种方式
-
默认工厂、静态工厂、实例工厂
-
默认工厂,Spring就是一个大工厂、大容器;默认使用无参的构造函数进行。这种方式,Bean必须含有无参的构造函数
<!-- 配置Bean --> <bean id="userDao" class="com.leehao.springlearning.spring1.UserDaoImpl"/> --------------------------------------------------------------------------- ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); userDao.save();
-
静态工厂,常用与spring整合其他框架(工具)。值得注意的是,一旦在spring中配置了静态工厂,所有的获取Bean都会通过静态工厂的工厂方法去创建,没有则返回null。
<!-- 静态工厂 --> <bean id="userDao2" class="com.leehao.springlearning.factory.StaticFactory" factory-method="createUserDao"/> --------------------------------------------------------------------------- public class StaticFactory { public static UserDao createUserDao() { System.out.println("Static Factory..."); return new UserDaoImpl(); } }
-
实例工厂,必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的。
public class InstanceFactory { /** * 实例工厂,不再是static的方法创建新对象 */ public UserDao createUserDao() { System.out.println("instance ...."); return new UserDaoImpl(); } } -------------------------------------------------------------------- <!-- 实例工厂 --> <bean id="myfac" class="com.leehao.springlearning.factory.InstanceFactory" /> <bean id="userDao3" factory-bean="myfac" factory-method="createUserDao" />
-
实验中发现,其实使用ClassXMLPathApplicationContext进行初始化的时候,无论是静态工厂、还是实例工厂,都会被解析完然后去实现。在解析完xml文件后,能够看到已经创建了各种工厂方法已经被执行了。
-
-
Bean的种类:普通、FactoryBean和BeanFactory
- 普通:<id= ,calss=A>,spring直接给创建A的实例,并返回
- BeanFactory生产任意的bean,是一个工厂类
- FactoryBean是一个特定的Bean,只生产某一特定的对象实例。Bean必须实现Factorybean接口,提供Getobject方法返回特定的bean. <id, class=FB> 创建FB实例,调用getObject,返回方法返回值。例如ProxyFactoryBean
5.5 Spring的分模块开发
和struts等框架一样,Spring也可以分模块各自开发,具有不同的xml文件,在总的applicationContext.xml文件中引入各个模块即可。
-
方式一:使用时,可以使用ApplicationContext工厂,加载多个xml文件进行初始化
-
方式二:多个文件引用到一个最终加载的文件中,使用import:
<import resource="com/application2.xml"/>