哈喽大家好,我是自学java的码小胡。我学习路线可能和大家都不太一样,在学习spring家族中,就直接学习了SpringBOOT,AlibabaSpringCloud,以及高速缓冲器Redis,消息队列RabbitMQ。
对没错我跳过了枯燥的Spring知识。今天我回头来学习spring,只要认真学习Spring很多概念都很好理解,比如IOC控制反转、AOP面向切面编程等等概念。来看看我的理解吧:
在讲spring之前,我们可以先弄懂一词 “高耦合” 是什么意思呢?
我自己将高耦合理解为 “牵一发而动全身” 。也就是说只要某个地方发生了改变,连带着很多地方都会发生改变。这就是我理解的高耦合。
那么在代码中是如何体现高耦合呢?那我们看一段非常熟悉的代码:
---数据代码实现:---
public class BookDaoImpl implements BookDao{
public void save(){
Systemctl.out.println("coding ma xioa hu .....1");
}
}
---业务层实现:---
public class BookServiceImpl implements BookService{
private BookDao bookDao = new BookDaoImpl();
public void save(){
bookDao.save();
}
}
数据层代码发生了变化:
---如果数据层代码发生变化,业务层怎么办呢?----
public class BookDaoImpl2 implements BookDao{
public void save(){
Systemctl.out.println("coding ma xioa hu...2 ");
}
}
数据层代码发生了变化怎么办呢???
那业务层的代码也要跟着动:private BookDao bookDao = new BookDaoImpl2();
那么这就是高耦合。
源代码发生了变化,就要重新编译、重新测试。
那么怎样才能降低耦合度呢???
spring的作用出现了:
问题:耦合度高
解决方法 :使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象。 从而达到解耦。
IOC控制反转:使用对象时,由主动new产生对象,转换为由外部(IOC)提供对象,此过程中对象的创建控制权由程序转移到外部。这种思想叫做控制反转。
IOC容器:就是用来充当IOC思想中的“外部”。IOC容器负责对象的创建、初始化等一些列工作,
Bean:IOC容器 创建或管理的对象统称为Bean
问题又来了:在程序中,service是需要调用dao。其中两者是有关系的,关系怎么办呢?
DI:依赖注入:在容器中建立Bean与Bean之间的依赖关系的整个过程,称为依赖注入。
IOC控制反转:当使用对象时,由主动new产生对象,转换为由外部(IOC)提供对象,此过程中对象的创建控制权由程序转移到外部。这种思想叫做控制反转。
IOC容器: IOC容器负责创建对象
Bean: IOC容器创建的对象,称之为“Bean”
DI: DI来绑定容器中的Bean之间的关系
OOP(Object Oriented Programming)面向对象编程。
OOP作用: 是做类、做对象、继承封装多态。
AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构。
AOP作用:在不惊动原始设计的基础上为其进行功能增强。 这就是spring理念:无侵入式编程。
而不管AOP还是OOP都是一种编程思想。
先找到程序的共性功能,进行抽取出来,写在通知类 。
在通知类中定义方法叫通知方法。
通知方法的作用是: 完成共性功能。
找到需要执行通知方法的方法,定义成切入点 。切入点就是匹配某些通知方法。
连接点是所有方法。
切入点和通知方法绑定后得到切面
AOP全称叫做 Aspect Oriented Programming 面向切面编程。它是为解耦而生的,解耦是程序员编码开发过程中一直追求的境界,AOP在业务类的隔离上,绝对是做到了解耦。
任何一个系统都是由不同的组件组成的,每个组件负责一块特定的功能,当然会存在很多组件是跟业务无关的,例如日志、事务、权限等核心服务组件,这些核心服务组件经常融入到具体的业务逻辑中,如果我们为每一个具体业务逻辑操作都添加这样的代码,很明显代码冗余太多。
因此我们需要将这些公共的代码逻辑抽象出来变成一个切面,然后注入到目标对象(具体业务)中去,AOP正是基于这样的一个思路实现的,通过动态代理的方式,将需要注入切面的对象进行代理,在进行调用的时候,将公共的逻辑直接添加进去,而不需要修改原有业务的逻辑代码,只需要在原来的业务逻辑基础之上做一些增强功能即可。