做为一个合格的 Java 开发人员, 你一定听说过 Spring 框架, 虽然会应用, 但却未必能够深入理解框架的原理, 只是像其它人一样, 泛泛的只是停留在理解的层面. 小编会带着大家一步步了解 Spring 框架.
struts:web 层, 比较简单(ValueStack 值栈, 拦截器);
hibernate:dao 层, 知识点杂;
spring:service 层, 重要, 讲多少用多少.
脑海中的架构:
一, spring 框架概述
1.1 什么是 spring
Spring 是一个开源框架, Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架, 由 Rod Johnson 在其著作 Expert One-On-One J2EE Development and Design 中阐述的部分理念和原型衍生而来. 它是为了解决企业应用开发的复杂性而创建的. 框架的主要优势之一就是其分层架构, 分层架构允许使用者选择使用哪一个组件, 同时为 J2EE 应用程序开发提供集成的框架. Spring 使用基本的 JavaBean 来完成以前只可能由 EJB 完成的事情. 然而, Spring 的用途不仅限于服务器端的开发. 从简单性, 可测试性和松耦合的角度而言, 任何 Java 应用都可以从 Spring 中受益. Spring 的核心是控制反转 (IoC) 和面向切面(AOP). 简单来说, Spring 是一个分层的 JavaSE/EE full-stack(一站式) 轻量级开源框架.
轻量级: 与 EJB 对比, 依赖资源少, 销毁的资源少.
分层: 一站式, 每一个层都提供的解决方案
web 层: struts,spring-MVC
service 层: spring
dao 层: hibernate,mybatis , jdbcTemplate -> spring-data
1.2 spring 由来
Expert One-to-One J2EE Design and Development
Expert One-to-One J2EE Development without EJB
1.3 spring 核心
Spring 的核心是控制反转 (IoC) 和面向切面(AOP)
1.4 spring 优点
方便解耦, 简化开发 (高内聚低耦合)
Spring 就是一个大工厂(容器), 可以将所有对象创建和依赖关系维护, 交给 Spring 管理
spring 工厂是用于生成 bean
AOP 编程的支持
Spring 提供面向切面编程, 可以方便的实现对程序进行权限拦截, 运行监控等功能
声明式事务的支持
只需要通过配置就可以完成对事务的管理, 而无需手动编程
方便程序的测试
Spring 对 Junit4 支持, 可以通过注解方便的测试 Spring 程序
方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架, 其内部提供了对各种优秀框架 (如: Struts,Hibernate,MyBatis,Quartz 等) 的直接支持
降低 JavaEE API 的使用难度
Spring 对 JavaEE 开发中非常难用的一些 API(JDBC,JavaMail, 远程调用等), 都提供了封装, 使这些 API 应用难度大大降低
1.5 spring 体系结构
Spring 框架是一个分层架构, 它饮食一系列的功能要素并被分为大约 20 个模块. 这些模块分为 Rore Container,Date Access/Integration,Web,AOP(Aspect Oriented Programming),Instrumentation 和测试部分, 如下图所示:
核心容器: beans,core,context,expression
二, 入门案例: IoC[掌握]
2.1 导入 jar 包
4 + 1 : 4 个核心(beans,core,context,expression) + 1 个依赖(commons-loggins...jar)
2.2 目标类
1. 提供 UserService 接口和实现类
2. 获得 UserService 实现类的实例
之前开发中, 直接 new 一个对象即可.
学习 spring 之后, 将由 Spring 创建对象实例 -> IoC 控制反转(Inverse of Control).
之后需要实例对象时, 从 spring 工厂 (容器) 中获得, 需要将实现类的全限定名称配置到 xml 文件中.
UserService 接口:
- public interface UserService {
- public void addUser();
- }
UserServiceImpl 实现类:
- public class UserServiceImpl implements UserService {
- @Override
- public void addUser() {
- System.out.println("a_ico add user");
- }
- }
2.3 配置文件
位置: 任意, 开发中一般在 classpath 下(src)
名称: 任意, 开发中常用 applicationContext.xml
内容: 添加 schema 约束
约束文件位置: spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\ xsd-config.html
- <?xml version="1.0" encoding="UTF-8"?>
- <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">
- <!-- 配置 service
- <bean> 配置需要创建的对象
- id : 用于之后从 spring 容器获得实例时使用的
- class : 需要创建实例的全限定类名
- -->
- <bean id="userServiceId" class="com.itheima.a_ioc.UserServiceImpl"></bean>
- </beans>
2.4 测试
- @Test
- public void demo02(){
- // 从 spring 容器获得
- //1 获得容器
- String xmlPath = "com/itheima/a_ioc/beans.xml";
- ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
- //2 获得内容 -- 不需要自己 new, 都是从 spring 容器获得
- UserService userService = (UserService) applicationContext.getBean("userServiceId");
- userService.addUser();
- }
三, 入门案例: DI[掌握]
DI Dependency Injection , 依赖注入
is a : 是一个, 继承.
has a: 有一个, 成员变量, 依赖.
- class B {
- private A a; //B 类依赖 A 类
- }
依赖: 一个对象需要使用另一个对象
注入: 通过 setter 方法进行另一个对象实例设置.
例如:
- class BookServiceImpl{
- // 之前开发: 接口 = 实现类 (service 和 dao 耦合)
- //private BookDao bookDao = new BookDaoImpl();
- //spring 之后 (解耦: service 实现类使用 dao 接口, 不知道具体的实现类)
- private BookDao bookDao;
setter 方法
}
模拟 spring 执行过程
1. 创建 service 实例: BookService bookService = new BookServiceImpl() ->IoC <bean>
2. 创建 dao 实例: BookDao bookDao = new BookDaoImple() ->IoC
3. 将 dao 设置给 service:bookService.setBookDao(bookDao); ->DI<property>
3.1 目标类
. 创建 BookService 接口和实现类
. 创建 BookDao 接口和实现类
. 将 dao 和 service 配置 xml 文件
. 使用 api 测试
3.1.1 dao
public interface BookDao {
public void addBook();
}
public class BookDaoImpl implements BookDao {
@Override
public void addBook() {
System.out.println("di add book");
}
}
3.1.2 service
public interface BookService {
public abstract void addBook();
}
public class BookServiceImpl implements BookService {
// 方式 1: 之前, 接口 = 实现类
// private BookDao bookDao = new BookDaoImpl();
// 方式 2: 接口 + setter
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void addBook(){
this.bookDao.addBook();
}
}
3.2 配置文件
<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">
<!--
模拟 spring 执行过程
创建 service 实例: BookService bookService = new BookServiceImpl() IoC <bean>
创建 dao 实例: BookDao bookDao = new BookDaoImpl() IoC
将 dao 设置给 service:bookService.setBookDao(bookDao); DI <property>
<property> 用于进行属性注入
name: bean 的属性名, 通过 setter 方法获得
setBookDao ##> BookDao ##> bookDao
ref : 另一个 bean 的 id 值的引用
-->
<!-- 创建 service -->
<bean id="bookServiceId" class="com.itheima.b_di.BookServiceImpl">
<property name="bookDao" ref="bookDaoId"></property>
</bean>
- <!-- 创建 dao 实例 -->
- <bean id="bookDaoId" class="com.itheima.b_di.BookDaoImpl"></bean>
- </beans>
3.3 测试
- @Test
- public void demo01(){
- // 从 spring 容器获得
- String xmlPath = "com/itheima/b_di/beans.xml";
- ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
- BookService bookService = (BookService) applicationContext.getBean("bookServiceId");
- bookService.addBook();
- }
来源: http://blog.51cto.com/13881968/2148425