Spring概述
1.1.1 spring 是什么
Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。
1.1.2 Spring 的发展历程
2017 年 9 月份发布了 spring 的最新版本 spring 5.0 通用版(GA)
1.1.3 spring 的优势
1.方便解耦,简化开发 (高内聚低耦合)
Spring就是一个大工厂(容器),用于创建对象(bean)和维护对象间的依赖关系。
2.AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能.
声明式事务的支持 ,只需要通过配置就可以完成对事务的管理,而无需手动编程;
3.方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序;
4.方便集成各种优秀框架
Spring支持各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等);
5.降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低;
1.1.4 spring 的体系结构
IoC 的概念和作用
2.1.1 编写jdbc的工程代码用于分析程序的耦合
- 修改pom.xml
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
- 创建类进行讲解
/**
程序的耦合
耦合:程序间的依赖关系
包括:类之间的依赖
方法间的依赖
解耦:
降低程序间的依赖关系
实际开发中:
应该做到:编译期不依赖,运行期才依赖
解耦的思路:
第一步:用反射创建对象 避免使用new关键字
第二步:通过读取配置文件来获取要创建的对象全限定类名
*/
public class JdbcDemo1 {
public static void main(String[] args) throws Exception{
//1.注册驱动
/*
* 使用的字符串 用反射的方式获取数据
* 而下面的是具体的驱动类(如果将pom中的依赖删掉将会在编译期报错,不符合实际开发环境)
* */
Class.forName("com.mysql.jdbc.Driver"); //有问题 写死了 表现出了解耦的思路 第二步
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/eesy","root","1234");
//3.获取操作数据库的预处理对象
PreparedStatement pstm = conn.prepareStatement("select * from account");
//4.执行sql 得到结果集
ResultSet rs = pstm.executeQuery();
//5.便利结果集
while (rs.next()){
System.out.println(rs.getString("name"));
}
//6.释放资源
rs.close();
pstm.close();
conn.close();
}
}
2.1.2 工厂模式解耦
- 创建表现层类 调用哪个业务层 发现需要降低耦合
- 解决方案 使用工厂模式解耦
首先需要一个配置文件来配置我们的service和dao
创建工厂 BeanFactory
/**
* 一个创建Bean对象的工厂
* Bean: 在计算机英语中,有可重用组件的含义。
* javaBean: 用java语言编写的可重用组件
* javabean > 实体类
* 他就是创建我们的service和dao对象的。
*
* 第一步:需要一个配置文件来配置我们的service和dao
* 配置的内容: 唯一标志=权限定类名(key=value)
* 第二步:通过读取配置文件中配置的内容,反射创建对象
*
* 我们的配置文件可以是xml也可以是properties
**/
public class BeanFactory {
//定义一个Properties对象
private static Properties props;
//使用静态代码块为Properties对象赋值
static {
try {
//实例化对象
props = new Properties();
//获取prperties文件的流对象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化properties失败");
}
}
/**
* 根据Bean的名称获取bean对象
* @param beanName
* @return
*/
public static Object getBean(String beanName){
Object bean = null;
try {
String beanPath = props.getProperty(beanName);
bean = Class.forName(beanPath).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
}
- 实现了降低耦合度
分析工厂模式中的问题进行改造
进行代码测试
结果如下 发现是多列的 对象被创建多次 执行效率没有单例对象高
解决方案 修改BeanFactory类 只创建一次 没必要多次创建
//定义一个Properties对象
private static Properties props;
//定义一个Map,用于存放我们要创建的对象。我们把它称之为容器
private static Map<String,Object> beans;
//使用静态代码块为Properties对象赋值
static {
try {
//实例化对象
props = new Properties();
//获取properties文件的流对象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
props.load(in);
//实例化容器
beans = new HashMap<String,Object>();
//取出配置文件中所有的Key
Enumeration keys = props.keys();
//遍历枚举
while (keys.hasMoreElements()){
//取出每个Key
String key = keys.nextElement().toString();
//根据key获取value
String beanPath = props.getProperty(key);
//反射创建对象
Object value = Class.forName(beanPath).newInstance();
//把key和value存入容器中
beans.put(key,value);
}
}catch(Exception e){
throw new ExceptionInInitializerError("初始化properties失败!");
}
}
/**
* 根据bean的名称获取对象
* @param beanName
* @return
*/
public static Object getBean(String beanName){
return beans.get(beanName);
}
执行结果为 单例的 对我们来说效果更好