0、楔子
- 为什么学Spring?
微服务成为当前项目架构和开发的主流。
学好Spring有助于进一步学习Spring Boot和Spring Cloud掌握微服务开发。 - 课程内容:
第一部分、Spring IOC工厂
第二部分、Spring AOP编程
第三部分、持久层集成
第三部分、事务处理
第四部分、MVC框架集成
第五部分、注解编程 - 学习建议:
认真听,记笔记
多练、多想、多问:怎么用→为什么这样做
坚持
第一章、Spring引入
1、简介
全称:SpringFramework5.X
- Spring的历史?
2002年,Rod Johnson概括了Java企业级应用程序开发的现状的和EJB框架的缺陷,并基于普通Java类和设计模式提出了更加简单的解决方案-interface21——衍生成为轻量级的J2EE开发解决方案Spring,于2004年发布第一个版本。
2、EJB的问题
全称:Enterprise Java Bean
- 问题1-运行环境苛刻
免费开源的Tomcat Web服务器只提供Servlet引擎,EJB需要服务器支持EJB容器
Orcale和IBM提供的支持Servlet和EJB的应用服务器软件( Weblogic、Websphere)收费闭源。不方便中小公司定制使用 - 问题2-代码移植性差
EJB代码需要实现不同服务器提供的接口,代码随着需要服务器变化
总结:EJB是重量级的框架
3、什么是Spring?
- 轻量级
对运行环境没有额外要求,可运行在提供Servlet引擎的服务器软件上
不需要实现任何额外接口,代码移植性好 - Java EE解决方案:
提供了传统JavaEE分层开发Controller、Service、DAO的一整套解决方案 - 整合设计模式
工厂
代理
模板
策略
4、设计模式简介
广义概念:面向对象设计中,解决特定问题的经典代码
侠义概念:GOF4人帮定义的23种设计模式
- 创建型:单例、原型、工厂、抽象工厂、建造者
- 结构型:适配器、桥接、组合、装饰者、外观、享元、代理
- 行为型:责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者
5、工厂设计模式
概念:通过工厂类创建对象,程序中借助工厂类方法获取对象
好处:解耦合
耦合:代码间的强关联,改变一方影响另一方;不利于代码维护
public class ActionServletController{
Userservice userService = new UserServiceImp();
//将接口的实现类硬编码到程序中
//使用另一种Service时,需要修改Controller代码
}
6、工厂模式编码实现
6-1、工厂类-消除调用对象和被调用对象之间的耦合
- JavaBean 省略了getter&setter结构
public class User {
String name;
String password;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
}
- 数据库访问对象 DAO
//Dao接口
public interface UserDao {
void save(User user);
void queryUserByNameAndPassword(String name,String password);
}
//Dao实现类 :主要体现工厂模式,这里Dao方法实现不具备参考意义
public class UserDaoImp implements UserDao{
@Override
public void save(User user) {
System.out.println("insert into user_t " + user);
}
@Override
public void queryUserByNameAndPassword(String name, String password) {
System.out.println("queryName = " + name + " queryPassword = " + password);
}
}
- 业务对象 Service
//Service接口
public interface UserService {
void register(User user);
void login(String name,String password);
}
//Service实现类
public class UserServiceImp implements UserService{
private UserDao userDao = new UserDaoImp();
@Override
public void register(User user) {
userDao.save(user);
}
@Override
public void login(String name, String password) {
userDao.queryUserByNameAndPassword(name,password);
}
}
- 工厂类
public class BeanFactory1 {
public static UserService getUserService(){
return new UserServiceImp();
}
public static User getUser(String name,String password){
return new User(name,password);
}
}
- 业务层调用类 使用单元测试类调用【Web中使用Controller类调用】
public class UserTest {
@Test
public void test1(){//不使用工厂模式
UserService userService = new UserServiceImp();
User tom = new User("tom","123456");
userService.register(tom);
userService.login("tom","123456");
}
@Test
public void test2(){//使用工厂模式
UserService userService = BeanFactory1.getUserService();
User tom = BeanFactory1.getUser("tom","123456");
userService.register(tom);
userService.login("tom","123456");
}
}
新增了工厂类和被调用对象之间的耦合
6-2、反射-消除工厂类与被调用对象之间的耦合
对象创建方式改变:new关键字+构造器 → 反射机制 + 构造器
import java.lang.reflect.Constructor;
public class BeanFactory2 {
public static UserService getUserService(){
//利用反射和无参构造器创建对象
UserService userService = null;
try {
Class clazz = Class.forName("UserServiceImp");
Constructor constructor = clazz.getConstructor();
userService = (UserService)constructor.newInstance();
} catch (Exception e) {//简化了异常处理;实际开发中不建议
e.printStackTrace();
}
return userService;
}
public static User getUser(String name,String password){
//利用反射和有参构造器创建对象
User user = null;
try {
Class clazz = Class.forName("User");
Constructor constructor = clazz.getConstructor(String.class, String.class);
user = (User)constructor.newInstance(name,password);
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
}
- 测试代码
import org.junit.Test;
public class UserTest {
@Test
public void useBeanFactory2(){//使用反射工厂
UserService userService = BeanFactory2.getUserService();
User tom = BeanFactory2.getUser("tom","123456");
userService.register(tom);
userService.login("tom","123456");
}
新增了工厂类和被调用类之间的耦合
6-3、配置文件-消除工厂类和被调用类之间的耦合
IDEA中文件夹属性:根据颜色区分
-
Source Root:源码目录
-
Resources Root : 源码需要的资源目录(图片配置文件)-作用等同于存放在Source Root目录下
-
Test Source Root:单元测试源码目录
-
Test Resource Root:单元测试需要的资源目录
-
Excluded:不会参与编译的文件目录
-
Generated Sources Root:文件夹中类经常需要重构和快速生成的的文件夹
IDAE中properties配置文件图标:
在Sources Root 或 Resource Root文件夹中新建配置文件
# properties文件中,以键值对的方式存储值
# 特殊的map :key 和 value的类型都是String类型
userService=UserServiceImp
# 第一个值是key值,一般设置和类名相关,方便识别
# 第二个值是实现类的全类名(包名+类名【不含后缀】)
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory3 {
//创建Properties类对象
private static Properties properties = new Properties();
//为减少IO读写-使用静态代码块,将配置文件中信息写入Properties集合对象
static {
InputStream inputStream=null;
try {
//使用系统类加载器获取读取配置文件,生成输入流
inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("applicationContext.properties");
//将输入流中的信息加载到Properties集合对象中
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}finally {
if (inputStream != null) {//关闭输入流
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public UserService getUserService(){
UserService userService=null;
try {
//通过key值获取实际的value值
Class clazz = Class.forName(properties.getProperty("userService"));
userService = (UserService)clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return userService;
}
}
- 测试代码
import org.junit.Test;
public class UserTest {
@Test
public void useBeanFactory3(){//使用反射加配置文件的工厂
UserService userService = BeanFactory3.getUserService();
System.out.println(userService);//多个测试用例代码重复,这里仅表示能获取到对象即可
}
}
新增了工厂类与key值的强耦合
6-4、将key作为方法参数-消除工厂类与具体的key值的耦合
static Object getBean(String key){
Object obj = null;
try {
Class clazz = Class.forName(key);
Constructor constructor = clazz.getConstructor();
obj = constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
工厂在获取对象时,只需要将配置文件中的key作为参数传入获取对象的方法
import org.junit.Test;
public class UserTest {
@Test
public void useCommonBeanFactory(){//使用通用工厂
UserService userService =(UserService) CommonBeanFactory.getBean("usrService");
System.out.println(userService);
}
}
6-5、工厂模式总结
作用:解决调用对象和被调用对象之间、以及中间层的强耦合。实现在配置文件中新增实现类的key-value,然后就能通过key获取对象使用
使用方式:
- 第一步、设计类(JavaBean)
- 第二步、配置文件注册类(key=value)
- 第三步、通过工厂类方法,传入key获取对象【需要强制类型转换】
7、Spring的本质
Spring 本质是一个工厂 :
- 工厂类:ApplicationContext类
- 配置文件:applicationContext.xml
第二章、第一个Spring程序
1、软件版本
- JDK 8及以上
- Maven 3.5以上
- IDEA 2018版本以上
- Spring版本5.X
2、环境搭建
2-1、Jar包
- 设置maven pom依赖文件
- maven中心仓库:https://mvnrepository.com/
2-2、配置文件
@copyright 文章内容来自bilibili UP主 孙帅suns