Spring简介
什么是spring
Spring架构图
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式组成,Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。
• Spring Core核心容器:核心容器提供Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
• Spring Context上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
• Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中
• Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
• Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
• Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
• Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
Spring的核心就是控制反转(IoC)和面向切面(AOP),总的来说,Spring是一个分层的Java轻量级框架之前重量级:EJB
注:刚接触spring时会出现很多不好理解的概念
Spring的作用
- Spring容器主要负责系统需要的对象生命周期的管理ioc di(控制反转,依赖注入,核心作用,解耦和),以及有依赖关系对象的注入最大程度上实现程序的解耦,实现程序的可重用以及系统的扩展和维护;
- 通过aop的实现集中管理程序共性问题,简化编码和维护,提供了mvc便于程序的分层设计 。
IOC和DI
- IOC(Inversion of Control)控制反转:说的是创建对象实例的控制权从代码控制剥离到IOC容器控制,实际就是你在xml文件控制,侧重于原理。
- DI(Dependency Injection)依赖注入:说的是创建对象实例时,为这个对象注入属性值或其它对象实例,侧重于实现。
IOC是什么
IOC—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”。
谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IOC是有专门一个容器来创建这些对象,即由IOc容器来控制对象的创建而不再显式地使用new;谁控制谁?当然是IOC容器控制了对象;控制什么?那就是主要控制了外部资源获取和生命周期(不只是对象也包括文件等)。
为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
用图例说明一下,传统程序设计如图1,都是主动去创建相关对象然后再组合起来:
图1 传统应用程序结构图
当有了IOC的容器后,在客户端类中不再主动去创建这些对象了,程序的结构图变成如图2所示:
图2 有IOC容器后的程序结构图
- IOC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序
- IOC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IOC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
IOC和DI
DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
谁依赖于谁:当然是应用程序依赖于IOC容器;
为什么需要依赖:应用程序需要IOC容器来提供对象需要的外部资源;
谁注入谁:很明显是IOC容器注入应用程序某个对象,应用程序依赖的对象;
注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
谁依赖于谁:当然是应用程序依赖于IOC容器;
为什么需要依赖:应用程序需要IOC容器来提供对象需要的外部资源;
谁注入谁:很明显是IOC容器注入应用程序某个对象,应用程序依赖的对象;
注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
IOC和DI有什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IOC而言,“依赖注入”明确描述了“被注入对象依赖IOC容器配置依赖对象”。
Spring入门程序
创建maven工程,添加jar包
<br />**通过maven引用:**
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<!-- spring4 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
Spring bean
一个简单的Spring bean
Spring bean 配置文件
创建Spring配置文件,并声明所有可用的Spring bean。
在resource目录下面创建applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 创建bean -->
<bean id="person" class="com.hzit.bean.Person">
<property name="userName" value="张三" />
</bean>
</beans>
测试代码
public static void main(String[] args) {
// 加载配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Person bean = context.getBean("person", Person.class);
bean.sayHello();
}
输出结果
演示减耦合效果
面向对象的概念,是一个很好的设计来打破系统进入一个组可重用的对象。然而,当系统变大,尤其是在Java项目,庞大的对象依赖关系将一直紧密耦合引起对象难以管理或修改。在这种情况下,可以使用Spring框架作为一个核心模块轻松高效地管理所有的对象依赖。
案例:使用不同的语言打招呼
1. 创建好统一的接口SalHello.java,定义打招呼的方法
2. 分别定义SayChinese.java和SayEnglish.java文件,分别实现打招呼方法
3. 定义帮助类SayHelp.java文件,用来统一打印信息
4. 在applicationContext.xml中配置bean
5. 测试
现在,已经实现了松耦合,当需要输出改变时,不必修改任何代码.java文件,只要修改ApplicationContext.xml文件
Spring的bean管理
1.Bean实例化的创建
2.Bean标签的常用属性
属性 | 作用 |
---|---|
id | 表示唯一标识 |
class |
表示ID对应类的全路径
singleton:是默认值 表示单例的意思
prototype:多例的
request:web项目中创建bean对象,存到request域中
session: web项目中创建bean对象,存到session域中
|
Spring依赖注入(DI)
在Spring框架中,依赖注入(DI)的设计模式是用来定义对象彼此间的依赖。
它主要有三种类型:
· Setter方法注入(最多的方式)
· 构造器注入
· 接口注入(很少用)
1.Setter方法注入
这是最流行最简单的DI注入方法,通过设置方法注入依赖。
实体类:
配置bean文件:
2.构造函数注入
此DI方法将通过构造函数注入依赖。
Name:对应实体类构造方法的里面的名称
setter方法还是构造函数注入?
Spring框架的设置有没有硬性规定,只需要使用适合你的项目需要的类型注入。然而,由于setter方法注入简单,它总是大部分使用场景的选择。
Spring集合 (List,Set,Map,Properties) 实例
下面例子向您展示Spring如何注入值到集合类型(List, Set, Map, and Properties)。 支持4个主要的集合类型:
<bean id="myList" class="com.hzit.bean.Customer">
<property name="empList">
<list>
<ref bean="emp1" />
<ref bean="emp2" />
<ref bean="emp3" />
</list>
</property>
<property name="empSet">
<set>
<ref bean="emp1" />
<ref bean="emp2" />
<ref bean="emp3" />
</set>
</property>
<property name="empMap">
<map>
<entry key="key1" value-ref="emp1" />
<entry key="key2" value-ref="emp2" />
<entry key="key3" value-ref="emp3" />
</map>
</property>
<property name="empPer">
<props>
<prop key="aa">123</prop>
<prop key="bb">456</prop>
</props>
</property>
</bean>
<bean id="emp1" class="com.hzit.bean.Dept">
<property name="name" value="zhangsan" />
<property name="pwd" value="123" />
</bean>
<bean id="emp2" class="com.hzit.bean.Dept">
<property name="name" value="lisi" />
<property name="pwd" value="456" />
</bean>
<bean id="emp3" class="com.hzit.bean.Dept">
<property name="name" value="wangwu" />
<property name="pwd" value="789" />
</bean>
Spring注入日期到bean属性
声明一个dateFormat bean,在“customer” Bean,引用 “dateFormat” bean作为一个工厂bean。该工厂方法将调用SimpleDateFormat.parse()自动转换成字符串Date对象。
使用注解注入的方式
常用的注解
注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired、Resource、Service、Controller、Repository、Component。
Component
标记类是组件,spring扫描注解配置时,会标记这些类要生成bean。
Controller、Service、Repository
分别标记的类是Controller控制层的类,Service服务层的类,Repository数据存储层也就是Dao层的类。
其实上面这三个标签都可以使用Compoent注解来使用
Autowired
表示自动注入属性,可以不写名称,根据类型去自动去查询
Resource
属于jdk的注解,通过指定bean名称注入
spring中使用注解
步骤一: 在applicationContext.xml配置文件中添加命名空间
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
步骤二:在beans中添加扫描的标签
<!-- 开启注解扫描 ,如果有多个包可以使用,(逗号)隔开 -->
<context:component-scan base-package="com.xx" />
步骤三:直接在需要的地方使用相关的注解