1. Spring启示录:
1.1 OCP原则:
什么是OCP?
OCP是软件七大开发原则的最基本原则: 开闭原则
对什么开? 对扩展开放
对什么闭? 对修改关闭
OCP原则是最核心的最基本的, 其他的六个原则都是为这个原则服务的
OCP开闭原则的核心是什么?
只要你在扩展功能的时候, 没有修改以前写好的代码, 那么你就是符合OCP原则的
反之, 如果在扩展系统功能的时候, 修改了之前的代码, 那么这个设计就是失败的, 违背了OCP原则.
当进行系统功能扩展的时候, 如果动了之前稳定的程序, 修改了之前的程序, 之前所有的程序都需要程序进行测试, 这是非常麻烦的.
1.2 依赖倒置原则(DIP原则):
什么是依赖倒置原则?
面向接口编程, 面向抽象编程, 不要面向具体编程
依赖倒置原则的目的?
降低程序的耦合度, 提高扩展力
什么叫符合依赖倒置?
上(业务层的代码) 不依赖 下(持久层的代码), 就是符合依赖倒置
什么叫不违背依赖倒置?
上 依赖 下, 就是违背
只要 下 代码一改动, 上 就受到牵连
-
// 业务层
-
public
class
UserServiceImpl
implements
UserService {
-
// 修改之前: 违背了依赖倒置原则
-
private
UserDao
userDao
=
new
UserDaoImplForMySQL();
-
-
// 修改之后: 不违背了,但是如果不new的话, userDao=null
-
private UserDao userDao;
// 直接写个接口
-
-
@Override
-
public
void
deleteUser
(){
-
// null调用方法就会空指针异常
-
userDao.deleteById();
-
}
-
}
1.3 控制反转IoC思想:
当前的程序设计, 显然违背了OCP又违背了DIP, 怎么办?
可以采用"控制反转"这种编程思想来解决问题
什么是控制反转?
控制反转: IoC (Inversion of Control)
反转是什么呢?
反转的是俩件事
第一件事: 我不在程序中采用硬编码的方式来new对象了 (new对象的权利交出去了)
第二件事: 我不在程序中采用硬编码的方式来维护对象的关系了 (对象之间的维护全交出去了), 例如下面代码:
-
// 业务层
-
public
class
UserServiceImpl
implements
UserService {
-
// 到底是UserDaoImplForMySQL还是UserDaoImplForOracle
-
// 和UserServiceImpl产生关系, 我不管了
-
private
UserDao
userDao
=
new
UserDaoImplForMySQL();
-
private
UserDao
userDao
=
new
UserDaoImplForOracle();
-
-
@Override
-
public
void
deleteUser
(){
-
userDao.deleteById();
-
}
-
}
控制反转: 是一种编程思想, 或者叫做一种新型的设计模式, 由于出现的比较新, 没有被纳入到GoF23中设计模式的范围内.
控制反转的作用: 让程序符合OCP原则又符合DIP原则
1.4 依赖注入DI:
Spring框架实现了控制反转IoC这种思想
Spring框架可以帮你new对象
Spring框架可以帮你维护对象和对象之间的关系
Spring是一种实现了IoC思想的容器
控制反转的实现方式有很多, 其中比较重要的叫做: 依赖注入(Dependency Injection, 简称DI)
控制反转是思想, 依赖注入是这种思想的具体实现
依赖注入DI, 又包括常见的俩种方式:
第一种, set注入 (执行set方法给属性赋值)
第二种, 构造方法注入 (执行构造方法给属性赋值)
-
public
class
UserServiceImpl
implements
UserService{
-
-
private UserDao userDao;
-
-
// set注入
-
public
void
setUserDao
(UserDao userDao) {
-
this.userDao = userDao;
-
}
-
-
// 构造方法注入
-
public
UserServiceImpl
(UserDao userDao) {
-
this.userDao = userDao;
-
}
-
-
@Override
-
public
void
deleteUser
() {
-
userDao.deleteById();
-
}
-
}
依赖注入中, "依赖"是什么意思? "注入"是什么意思?
依赖: 对象和对象之间的关联关系(A对象中有B, B对象中有C)
注入: 是一种手段, 通过这种手段, 可以让A对象和B对象产生关系
依赖注入: 对象A和对象B之间的关系, 靠注入的手段来维护, 而注入包括: set注入和构造注入
Spring通过依赖注入的方式来完成Bean管理
Bean管理说的是:
Bean对象的创建
Bean对象中属性的赋值(或者叫做Bean对象之间关系的维护)
2. Spring概述:
Spring是一个轻量级的控制反转IoC和面向切面AOP的容器框架
Spring最初的出现是为了解决EJB臃肿的设计, 以及难以测试等问题
Spring为简化而生, 让程序员只需关注核心业务的实现, 尽可能的不再关注非业务逻辑代码(事务控制,安全日志等)
Spring把创建好的对象存储到一个什么样的数据结构中呢?
Map<String,Object>
在配置文件中配置的类必须是自定义的吗? 可以使用JDK中的类, 例如: java.util.Date?
-
// xml
-
<bean id="dateBean" class="java.util.Date"/> // 不是
3. 第一个spring程序:
Spring是怎么实例化对象的?
默认情况下, spring通过反射机制, 调用类的无参构造方法来实例化对象, 实现原理如下:
class clazz = Class.forName("com.powernode.bean.User");
Object obj = clazz.newInstance();
ApplicationContext接口的超级父接口是: BeanFactory (翻译为Bean工厂, 就是能够生产Bean对象的一个工厂对象)
BeanFactory是IoC容器的顶级接口
Spring的IoC容器底层实际上使用了工厂模式
Spring底层的IoC是怎么实现的?
XML解析 + 工厂模式 + 反射机制
ApplicationContext是BeanFactory的子类, 为什么使用ApplicationContext?
因为它方法更多, 功能更丰富
-
// xml
-
<!-- 配置bean, 这样spring才可以帮助我们管理这个对象 -->
-
<!-- bean标签的俩个重要属性:
-
id: 是这个bean的身份证号, 不能重复, 是唯一标识
-
class: 必须填写类的全路径, 全限定类名(带包名的类名)
-
-->
-
<bean id=
"userBean" class=
"com.powernode.bean.User"/>
-
-
// @Test
-
public
void
testFirstSpringCode
() {
-
// 第一步: 获取Spring容器
-
// ApplicationContext 翻译为: 应用上下文, 其实就是Spring容器
-
// ApplicationContext 是一个接口
-
// ApplicationContext 接口下有很多实现类, 其中一个就是ClassPathXmlApplicationContext
-
// ClassPathXmlApplicationContext 专门从类路径当中加载spring配置文件的一个spring上下文对象
-
// 这行代码只要执行, 就相当于启动了spring容器, 解析spring.xml文件, 并且实例化所有的bean对象, 放到bean容器当中
-
ApplicationContext
ctx
=
new
ClassPathXmlApplicationContext(
"spring.xml");
-
// 下面的代码也没问题:
-
BeanFactory
beanFactory
=
new
ClassPathXmlApplicationContext(
"spring.xml");
-
-
// 第二步: 根据bean的id从spring容器中获取这个对象
-
// 如果id不存在, 不会返回null, 会报错
-
Object
userBean
= ctx.getBean(
"userBean");
-
// 不想强制类型转换, 可以使用下面的代码: (通过第二个参数, 指定返回的bean的类型)
-
User
userBean1
= ctx.getBean(
"userBean", User.class);
-
-
System.out.println(userBean);
-
}
注意不是在调用getBean()方法的时候创建对象, 执行以下代码的时候, 就会实例化对象, 调用无参构造
-
// @Test
-
public
void
testBeginInitbean
(){
-
// 注意不是在调用getBean()方法的时候创建对象, 执行以下代码的时候, 就会实例化对象
-
new
ClassPathXmlApplicationContext(
"spring.xml");
-
}
转载:https://blog.csdn.net/qq_68993495/article/details/128893014