Spring
1 Spring 简介
1.1 Spring是什么
Spring : 春天 —>给软件行业带来了春天
2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。
很难想象Rod Johnson的学历 , 他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术
官网 : http://spring.io/
官方下载地址 : https://repo.spring.io/libs-release-local/org/springframework/spring/
GitHub : https://github.com/spring-projects
1.2 Spring的优点
1、Spring是一个开源免费的框架 , 容器 .
2、Spring是一个轻量级的框架 , 非侵入式的 .
3、控制反转 IoC(方便解耦,简化开发) , 面向切面 AOP
4、对事务的支持 , 对框架的支持
5、方便程序的测试
6、方便集成各种优秀框架
7、降低JavaEE API的使用难度
8、
…
一句话概括:
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
1.3 Spring的体系结构
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 .
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
核心容器(Core Container):核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。
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。
1.4 拓展
Spring Boot与Spring Cloud
Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务;
Spring Cloud是基于Spring Boot实现的;
Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;
Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置 , Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
SpringBoot在SpringClound中起到了承上启下的作用,如果你要学习SpringCloud必须要学习SpringBoot。
2 Spring快速入门
2.1 Spring程序开发步骤
3 Spring配置文件
3.1 配置详解
<bean id="userDao" class="com.raphuscucullatus.dao.impl.UserDaoImpl"></bean>
@Test
public void testScope(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao)app.getBean("userDao");
UserDao userDao2 = (UserDao)app.getBean("userDao");
System.out.println("userDao的地址:"+userDao);
System.out.println("userDao2的地址:"+userDao2);
}
配置获取实例的方式
<bean id="userDao" class="com.raphuscucullatus.dao.impl.UserDaoImpl" scope="singleton"
init-method="init" destroy-method="destroy"></bean>
<bean id="userDao" class="com.raphuscucullatus.factory.StaticFactory" factory-method="getUserDao"></bean>
<bean id="factory" class="com.raphuscucullatus.factory.Factory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"/>
依赖注入(Depandency Injection)
方式一:构造方法
spring核心配置文件
<bean id="userService" class="com.raphuscucullatus.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
Dao层
package com.raphuscucullatus.dao.impl;
import com.raphuscucullatus.dao.UserDao;
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("UserDaoImpl无参构造创建实例");
}
public void init (){
System.out.println("UserDaoImpl初始化");
}
public void destroy (){
System.out.println("UserDaoImpl被销毁");
}
@Override
public void save() {
System.out.println("save running....");
}
}
服务层
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
}
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
在控制层进行测试
package com.raphuscucullatus.controller;
import com.raphuscucullatus.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)app.getBean("userService");
userService.save();
}
}
方式二:set方法
spring核心配置文件
<bean id="userDao" class="com.raphuscucullatus.dao.impl.UserDaoImpl" scope="singleton"
init-method="init" destroy-method="destroy"></bean>
<bean id="userService" class="com.raphuscucullatus.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
-
或使用p命名空间配置依赖注入(了解) 首先在跟标签beans属性中引入p命名空间,如下
xmlns:p="http://www.springframework.org/schema/p"
? 之后即可在bean标签中可通过p:userDao-ref属性配置依赖注入
<bean id="userService" class="com.raphuscucullatus.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
Dao层
package com.raphuscucullatus.dao.impl;
import com.raphuscucullatus.dao.UserDao;
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("UserDaoImpl无参构造创建实例");
}
public void init (){
System.out.println("UserDaoImpl初始化");
}
public void destroy (){
System.out.println("UserDaoImpl被销毁");
}
@Override
public void save() {
System.out.println("save running....");
}
}
服务层
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
@Override
public void save() {
userDao.save();
}
}
在控制层进行测试
package com.raphuscucullatus.controller;
import com.raphuscucullatus.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)app.getBean("userService");
userService.save();
}
}
可注入的数据类型
除了引用Bean的注入, 普通数据类型,集合等都可以在容器中注入
配置文件:
<bean id="userDao" class="com.raphuscucullatus.dao.impl.UserDaoImpl" scope="singleton"
init-method="init" destroy-method="destroy">
<property name="userName" value="张三"/>
<property name="age" value="18"/>
<property name="userNameList">
<list>
<value>狗蛋</value>
<value>李四</value>
<value>王五</value>
</list>
</property>
<property name="userMap">
<map>
<entry key="狗蛋" value-ref="狗蛋"></entry>
<entry key="李四" value-ref="李四"></entry>
<entry key="王五" value-ref="王五"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="手机号">15159044077</prop>
<prop key="邮箱">15511u5@qq.com</prop>
</props>
</property>
</bean>
<bean id="狗蛋" class="com.raphuscucullatus.bean.User">
<property name="name" value="狗蛋"></property>
<property name="age" value="34"></property>
</bean>
<bean id="李四" class="com.raphuscucullatus.bean.User">
<property name="name" value="李四"></property>
<property name="age" value="24"></property>
</bean>
<bean id="王五" class="com.raphuscucullatus.bean.User">
<property name="name" value="王五"></property>
<property name="age" value="15"></property>
</bean>
自定义类User:
package com.raphuscucullatus.bean;
public class User {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
userDaoImpl
package com.raphuscucullatus.dao.impl;
import com.raphuscucullatus.bean.User;
import com.raphuscucullatus.dao.UserDao;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class UserDaoImpl implements UserDao {
private String userName;
private int age;
private List<String> userNameList;
private Map<String, User> userMap;
private Properties properties;
public void setUserName(String userName) {
this.userName = userName;
}
public void setAge(int age) {
this.age = age;
}
public void setUserNameList(List<String> userNameList) {
this.userNameList = userNameList;
}
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public UserDaoImpl() {
System.out.println("UserDaoImpl无参构造创建实例");
}
public void init (){
System.out.println("UserDaoImpl初始化");
}
public void destroy (){
System.out.println("UserDaoImpl被销毁");
}
@Override
public void save() {
System.out.println("用户名:"+userName+",年龄:"+age);
System.out.println(userNameList);
System.out.println(userMap);
System.out.println(properties);
System.out.println("save running....");
}
}
在控制层进行测试
package com.raphuscucullatus.controller;
import com.raphuscucullatus.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserControllerTest {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)app.getBean("userService");
userService.save();
}
}
3.2 引入其他配置文件
实际开发中, Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载
<import resource="applicationContext-user.xml"/>
例如将注入自定义类User的配置单独放入applicationContext-user.xml文件中,在原配置文件中引入此配置即可:
<bean id="userDao" class="com.raphuscucullatus.dao.impl.UserDaoImpl" scope="singleton"
init-method="init" destroy-method="destroy">
<property name="userName" value="张三"/>
<property name="age" value="18"/>
<property name="userNameList">
<list>
<value>狗蛋</value>
<value>李四</value>
<value>王五</value>
</list>
</property>
<property name="userMap">
<map>
<entry key="狗蛋" value-ref="狗蛋"></entry>
<entry key="李四" value-ref="李四"></entry>
<entry key="王五" value-ref="王五"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="手机号">15159044077</prop>
<prop key="邮箱">15511u5@qq.com</prop>
</props>
</property>
</bean>
<import resource="applicationContext-user.xml"/>
applicationContext-user.xml文件中配置
<bean id="狗蛋" class="com.raphuscucullatus.bean.User">
<property name="name" value="狗蛋"></property>
<property name="age" value="34"></property>
</bean>
<bean id="李四" class="com.raphuscucullatus.bean.User">
<property name="name" value="李四"></property>
<property name="age" value="24"></property>
</bean>
<bean id="王五" class="com.raphuscucullatus.bean.User">
<property name="name" value="王五"></property>
<property name="age" value="15"></property>
</bean>
这样配置不会影响程序运行结果.
4 Spring相关API
4.1 Spring继承体系
4.2 ApplicationContext的实现类
1) ClassPathXmlApplicationContext 它是从类的根路径下加载配置文件 推荐使用这种 2) FileSystemXmlApplicationContext 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。 3) AnnotationConfigApplicationContext 当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
package com.raphuscucullatus.controller;
import com.raphuscucullatus.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class UserControllerTest {
public static void main(String[] args) {
ApplicationContext app = new FileSystemXmlApplicationContext("D:\\JavaDevelop\\IDE\\workspace\\spring\\spring_ioc\\src\\main\\resources\\applicationContext.xml");
UserService userService = (UserService)app.getBean("userService");
userService.save();
}
}
4.3 getBean方法的使用
package com.raphuscucullatus.controller;
import com.raphuscucullatus.bean.User;
import com.raphuscucullatus.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class UserControllerTest {
public static void main(String[] args) {
ApplicationContext app = new FileSystemXmlApplicationContext("D:\\JavaDevelop\\IDE\\workspace\\spring\\spring_ioc\\src\\main\\resources\\applicationContext.xml");
UserService userService = app.getBean(UserService.class);
userService.save();
}
}
|