Spring 学习之IOC,AOP,DI的理解
IOC,AOP,DI这个三个概念是理解Spring的基础,良好的理解好这三个概念将对我们理解Spring是有所帮助.本文只是对其概念些许拙见,并问讲具体实现.
IOC And DI
- 什么是IOC?
IOC, 中文名称控制反转, 它是一种编程思想. 顾名思义,要理解什么是IOC,那么我们按照名字拆分’控制’,‘反转’;
首先我们需要理解控制了什么?例如在下面的代码块,类A 依赖了类B,在传统的编程模型中我们是在类A中直接是new关键字创建B对象.
public class A {
private B b;// = new B();
// 省略getter/setter
}
public class B {
// some field
}
当有了IOC容器的时候, 那么创建B这个对象操作的控制权就不由自己来控制, 而是交给了IOC容器, 当我们需要B这个对象的时候, 直接去向IOC容器要; 相当于IOC容器拥有对象的控制权,管理着这些对象(也就是控制了对象创建,销毁等一系列管理对象的操作), 这当然省去了我们不少自己管理对象的麻烦事.
那反转的又是什么?当是我们对对象的控制权,反转之前那么控制权在自己手里, 反转之后控制权交给了IOC容器,我们的控制权发生了反转.
- IOC 解决了什么问题?
它解决对象之间的解耦问题.例如,在我们UserService里面引用了UserDao对象,项目刚开始我们直接使用JDBC的保存方法,但是某一天我们引入了myBatis, 需要把项目里面所有的使用JDBC的改成myBatis,如果传统的编码模式, 那么我们需要把所有使用到JdbcUserDaoImpl 的实例 , 手动改为new MyBatisUserDaoImpl(); 代码侵入性强, 而且也是强耦合的,牵一发动全身.
但是当我们使用了IOC技术, 那么我们只需要更改IUserDao实现为mybatis的实现方法, 那么当我们需要使用IUserDao 的实例对象时候 直接去容器里面拿, 而且之前的业务代码不需要重构.
public interface IUserDao {
void saveUser(User user);
}
public class JdbcUserDaoImpl implements IUserDao{
public void saveUser(User user) {
Sytem.out.println("JDBC save method");
}
}
public class MyBatisUserDaoImpl implements IUserDao{
public void saveUser(User user) {
Sytem.out.println("MyBatis save method");
}
}
@Slf4j
public class UserService {
private IUserDao userDao; // new JdbcUserDaoImpl ()
public void saveUser(User user) {
log.info("begin at time",System.currentTimeMillis);
userDao.saveUser(user);
log.info("end at time",System.currentTimeMillis)
}
public void queryUserById(Integer id) {
log.info("begin at time",System.currentTimeMillis);
Sytem.out.println("queryUserById");
log.info("end at time",System.currentTimeMillis)
}
}
- IOC/DI的区别
IOC/DI本质上描述的是一件事情,只是说站在的角度不一样.
IOC是站在对象的角度来描述,也就是说对象把它的创建销毁等一系列管理权力交给了IOC容器,进行了控制反转.
而DI是站在容器的角度,也就是说容器会把对象里面依赖的其他对象进行注入,比如容器发现上面的UserService 里面的userDao需要一个实例对象,那么容器会对该对象进行实例注入.
AOP
-
什么是AOP?
AOP面向切面编程.
在UserService中,对我们每个方法执行的前后都加入开始结束时间,这些代码与我们的业务逻辑无关,本身我们业务逻辑复杂,然而现在又掺杂着各种与业务逻辑无关的代码, 比如方法的执行时间等日志的监控, 增加了我们代码的复杂度, 同时不利于维护,有多少方法 就要加多少重复的代码.代码侵入性大而且耦合性强. 同时我们就叫这些代码为横切代码.
我们如果能将这些共同的横切逻辑抽离出来, 并且在不污染原代码逻辑的情况下整合到我们方法执行体中, 通过一种技术实现与业务代码的解耦,那么我们就可以叫这种技术为面向切面编程. -
AOP解决了什么问题?
在不改变(不侵入)原有逻辑的情况下, 增强横切逻辑,与业务代码解耦.,避免了大量的横切逻辑重复问题. -
为什么叫面向切面编程?
我们的’切’是指横切逻辑,保证我们原有的代码逻辑不动, 对我们的切面进行编程,所以叫面向切面编程
'面’是指的是我们的横切逻辑往往在很多方法里面都有,那么许多的这方法的切点构成了一个面, 所以可以理解为切面