烂笔头

扬帆起航,再出发!!!

0%

spring概述

Spring概述

Spring是什么?

Spring是分层的 java SE/EE应用 全栈轻量级开源框架,以IOC(控制反转)和AOP(切面编程)为内核,提供了展现层Spring MVC 和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的java EE企业应用开源框架。Spring官网

Spring优势

方便解藕、简化开发

通过Spring提供的IOC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等很底层的需求编写代码,可以更专注于上层的应用开发。

AOP编程的支持

通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应对。

声明式事务的支持

可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。

方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

方便集成各种优秀框架

Spring可以降低各种框架的使用难度,提供了对各种优秀框架的直接支持。

降低java EE api的使用难度

Spring对JavaEE API(JDBC、JavaMail、远程调用等)进行了封装,使这些API的使用难度大大降低。

源码是经典学习的案例

Spring的源码设计精妙、结构清晰、匠心独用、处处体现着大师对java设计模式灵活运用以及对java技术的高深造诣,它的源码无疑是java技术的最佳实践的范例。

Spring体系结构

Spring体系结构图

程序的耦合及解藕

曾经项目中的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package io.github.lonelyMrZhang;

import java.sql.*;

/**
* @description: 程序耦合事例
* @author: lonely.mr.zhang
* @date: 2020/6/11 8:42 下午
*/
public class JdbcDemo1 {
public static void main(String[] args) throws SQLException {
// 1、注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 2、获取连接
Connection con = DriverManager.getConnection("jdbc:mysql://192.168.31.254:3306/coupling_code", "root", "2486");

// 3、获取操作数据库的预处理对象
PreparedStatement preparedStatement = con.prepareStatement("select * from account");

// 4、执行sql,得到结果集
ResultSet resultSet = preparedStatement.executeQuery();
// 5、遍历结果
while (resultSet.next()){
System.out.println(resultSet.getString("name"));
}
// 6、释放资源
resultSet.close();
preparedStatement.close();
con.close();
}
}

项目GitHub地址

JdbcDemo1类依赖com.mysql.jdbc.Driver()类,如果没有Driver的jar包,代码在编译时将会报错。

耦合:程序间的依赖关系,包括类之间的依赖、方法间的依赖

解藕:降低程序间的依赖关系,我们在实际开发中应该做到编译器不依赖,运行期才依赖。

将第一步注册驱动改为下面通过反射的方式注册便可降低耦合

Class.forName("com.mysql.jdbc.Driver");

总结:

1、使用反射来创建对象,避免使用new关键字
2、通过读取配置文件来获取要创建的对象的全限定类名

工厂模式解藕

分析:要解藕的创建对象需要以下两步:

1、需要一个配置文件来配置我们的service和dao,配置文件的内容:唯一标识ID=全限定类名(KV健值对)
2、通过读取配置文件中配置,反射创建对象

在代码中创建BeanFactory类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package io.github.lonelyMrZhang.factory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
* @description: 创建Bean对象的工厂
* @author: lonely.mr.zhang
* @date: 2020/6/12 4:20 下午
*/
public class BeanFactory {

/**
* 分析:
* Bean: 在计算机英语中有可重用组件的含义
* javaBean:用java语言编写的可重用组件,javaBean > 类
*
* BeanFactory就是用来创建service和dao对象的
*
* 要解藕的创建对象需要以下两步:
* 1、需要一个配置文件来配置我们的service和dao,配置文件的内容:唯一标识ID=全限定类名(KV健值对)
* 2、通过读取配置文件中配置,反射创建对象
*
* 配置文件可以是xml也可以是properties
*/

private static Properties properties;
//初始化配置文件对象
static {
try {
properties = new Properties();
//避免使用 new File()的方式,因为文件路径不好控制
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
properties.load(in);
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化properties失败!");
}
}

/**
* 根据beanName获取Bean对象
*
* @param beanName
* @return
*/
public static Object getBean(String beanName){
Object bean = null;
try {
String beanPath = properties.getProperty(beanName);
bean = Class.forName(beanPath).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}

}

在需要创建对象的地方通过BeanFactory工厂创建,如下所示:

1
2
//        IAccountService accountService = new AccountServiceImpl();
IAccountService accountService = (IAccountService) BeanFactory.getBean("accountService");

通过以上方式就可降低代码间的耦合程度,当AccountServiceImpl实现类不存在时,只会产生运行时异常,而不会在编译器就出错。

上述方案的Bean工厂获取对象时每次都会创建一个新的实例,而在我们平时的开发过程中,service、dao对象都为单例模式模式,所以我们可以将BeanFactory设计为单例模式从而进一步优化。见链接代码。

项目GitHub地址

IOC的概念

IOC(控制反转)把创建对象的权利交给框架,是框架的重要特征,包括依赖注入(DI)和依赖查找(Dependency Lookup),IOC的作用就是削减程序中的耦合。

您的支持就是我更新的动力!有钱的捧个钱场,没钱的捧个人场,谢谢大家!