1.Spring概述
1.1.Spring介绍
Spring是轻量级Java EE应用开源框架(官网: http://spring.io/ ),它由Rod Johnson创为了解决企业级编程开发的复杂性而创建
1.2.简化应用开发体现在哪些方面?
-
IOC
解决传统Web开发中硬编码所造成的程序耦合
-
AOP
实现在运行期间不修改源代码对程序进行增强
-
粘合剂
Spring是一个超级粘合平台,除了自己提供功能外,还提供整合其他技术和框架的能力
1.3.Spring的体系结构
Spring 框架根据功能的不同大体可分为 Data Access/Integration(数据访问与集成)
、Web
、AOP、Aspects、Instrumentation(检测)、Messaging(消息处理)
、Core Container(核心容器)
和 Test
。
- Core Container: 框架的最基础部分,提供控制反转和依赖注入特性
- AOP :提供了面向切面的编程的实现
- Data Access/Integration:简化了持久层的操作
- Web:提供了Spring MVC Web 框架实现以及与Servlet、WebSocket的集成
- Test:方便程序的测试
1.4.Spring的发展历程
-
1997年IBM提出了EJB的思想
-
1998年,SUN制定开发标准规范EJB1.0
-
1999年,EJB1.1发布
-
2001年,EJB2.0发布
-
2003年,EJB2.1发布
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雏形)
-
2006年,EJB3.0发布
-
2017年9月发布了Spring的最新版本Spring5.0通用版x
2.Spring IOC
2.1.程序的耦合
-
耦合:耦合指的就是对象之间的依赖关系。对象之间的耦合越高,维护成本越高。
-
案例:没有引入IOC容器时系统的Web层、业务层、持久层存在耦合
/** * 持久层实现类 */ public class UserDaoImpl implements UserDao { @Override public void addUser(){ System.out.println("insert into tb_user......"); } }
/** * 业务层实现类 */ public class UserServiceImpl implements UserService { //硬编码:此处有依赖关系 private UserDao userDao = new UserDaoImpl(); public void addUser(){ userDao.addUser(); } }
/** * 模拟表现层 */ public class Client { public static void main(String[] args) { //硬编码:此处有依赖关系 UserService userService = new UserServiceImpl(); userService.addUser(); } }
-
问题分析:
上边的代码service层在依赖dao层的实现类,此时如果更改dao了层的实现类或此时没有dao层实现类,编译将不能通过。
-
IOC(工厂模式)解耦:
- 把所有的dao和service对象使用配置文件配置起来
- 当服务器启动时读取配置文件
- 把这些对象通过反射创建出来并保存在容器中
- 在使用的时候,直接从工厂拿
2.2.IOC解决程序耦合
2.2.1.创建工程
2.2.2.什么是IOC
-
IOC (Inverse of Control)即控制反转:由ioc容器来创建依赖对象,程序只需要从IOC容器获取创建好的对象。
-
原来:
我们在获取对象时,都是采用new的方式。是主动的。
-
现在:
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。
2.2.3.IOC(工厂模式)解耦
-
案例一
/** * bean工厂 */ public class BeanFactory_v1 { /** * 获得UserServiceImpl对象 * @return */ public static UserService getUserService(){ return new UserServiceImpl(); } /** * 获得UserDaoImpl对象 * @return */ public static UserDao getUserDao(){ return new UserDaoImpl(); } }
问题:我们在开发中会有很多个service和dao,此时工厂类就要添加无数个方法。
-
案例二
#1、配置要使用的dao和service UserDao=com.by.dao.UserDaoImpl UserService=com.by.service.UserServiceImpl
/** * bean工厂 */ public class BeanFactory_v2 { private static Properties prop = new Properties(); /** * 根据全类名获取bean对象 * @param beanName * @return * @throws ClassNotFoundException */ public static Object getBean(String beanName) { try { //不能使用:web工程发布后没有src目录 //InputStream is = new FileInputStream("src/bean.properties"); InputStream is = BeanFactory_v2.class.getClassLoader() .getResourceAsStream("bean.properties"); prop.load(is); return Class.forName(prop.getProperty(beanName)).newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(prop.get("UserService")); System.out.println(getBean("UserService")); } }
/** * 业务层实现类 */ public class UserServiceImpl implements UserService { private UserDao userDao = (UserDao) BeanFactory.getBean("UserDao"); public void addUser(){ userDao.addUser(); } }
测试:
问题:/** * 模拟表现层 */ public class Client { public static void main(String[] args) { //直接引用接口实现类 for (int i = 0; i < 5; i++) { UserService userService = (UserService)BeanFactory.getBean("UserService"); System.out.println(userService); } } }
- 每次都会创建新的对象
- 程序运行时才创建对象(读取配置文件)
-
案例三
package com.by.factory; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Set; /** * bean工厂 */ public class BeanFactory_v3 { //定义一个容器,用于存放对象 private static Map<String, Object> beans = new HashMap<>(); /** * 加载配置文件 */ static { try { //2、读取配置文件 //不能使用:web工程发布后没有src目录 //InputStream is = new FileInputStream("src/bean.properties"); InputStream is = BeanFactory_v3.class.getClassLoader() .getResourceAsStream("bean.properties"); //3、通过反射创建对象,把对象存到容器中 Properties prop = new Properties(); prop.load(is); Set<Map.Entry<Object, Object>> entrySet = prop.entrySet(); for (Map.Entry<Object, Object> entry : entrySet) { String key = entry.getKey().toString(); String beanName = entry.getValue().toString(); Object value = Class.forName(beanName).newInstance(); beans.put(key, value); } } catch (Exception e) { e.printStackTrace(); } } /** * 4、在使用的时候,直接从工厂拿 * @param beanName * @return */ public static Object getBean(String beanName) { try { return beans.get(beanName); } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(getBean("UserService")); } }