IoC(Inversion of Control):
在传统的java程序编写中如果调用方法或类者,必须要对被调用者进行实例化,即必须要通过new 被调用者类
,才能对被调用者类中的方法、成员进行操作。在开发某一个项目时必然会出现很多类来完善项目的需求,并且类与类之间有很多的交互和依赖,代码将会很变得很难高度耦合和有效的维护。spring中的IoC便解决了这一问题。IoC即控制反转,它主要是将控制权原本由被调用者转换成spring的容器。也就是说由spring生成(实例化)这些对象,并控制这些类的调用。IoC还有一种叫法是DI(Dependency Injection),即依赖注入。在spring容器启动的时候就会自动的将一些类、方法、成员装入一个bean容器中,在之后调用者调用这些类、方法、成员时就不需要再次实例化。这样可以避免多次对被调用者进行实例化,调用者不需要再像之前有那么多重复的操作。
简单来说,spring的IoC就好比是一个餐厅,在餐厅开饭之前厨师已经通过之前的很多步骤做好了很多菜。等到开饭后,很多买饭者可以任意挑选自己喜欢吃的菜,但是不需要关心这些菜的做法及过程,只管尽情的享用即可。
AOP(Aspect Oriented Programming):
AOP即面向切面编程。个人理解是将一个本身完整的东西,但是因为需要对操作者增加一些权限,必须将这个东西切开,然后给里面加一些想要的拦截。比如说一个酒店服务员你可以给顾客端茶递水,但是一个酒店打扫卫生的员工就不允许给顾客端茶递水。所以就需要酒店经理提前给这些员工分配自己的工作范围。
spring实现AOP需要引入java中的代理,其主要目的是为了增加拦截器。在java中有两种代理方式,JDK代理和CGLIB代理。前者代理需要本实现一个接口,在代理这个类时只能代理接口中的类。后者代理不需要实现接口,但是对于本类中的final方法不能进行代理。具体代理方式自行查看。
先看看我实现IOC和AOP的总体思路框图
接下来看看代码的简单实现
首先是一个SatProxy类,其中共有三个成员,成员的get()和set()方法就不写了
private Object proxy; //代理对象//代理类的本对象
private Object object; //代理类的本对象
private boolean isInjection; //判断成员是否注入
在这个类中还有三个拦截器方法。分别为doBefore()、doAfter()、dealException()。其主要是为了对一些需要拦截的方法进行置前、置后、异常拦截(为了简单只写了这三个拦截方法,spring中还有其他拦截方法)
protected boolean doBefore(Object[] args, Class<?> klass, Method method) {
IntercepterFactory intercepterFactory = new IntercepterFactory(); //拦截器工厂
IntercepterTargetDefination itd = new IntercepterTargetDefination
(klass, method); //通过从ProxyFactory中传过来的method,klass确定目标拦截方法
List<IntercepterMethodDefination> intercepterMethodList =
intercepterFactory.getBeforeMethodList(itd); //通过目标拦截方法找到拦截方法List
if (intercepterMethodList == null) { //如果没有找到相关的拦截器
return true;
}
for (IntercepterMethodDefination imd : intercepterMethodList) {
Method intercepterMethod = imd.getMethod();
Object object = imd.getObject();
boolean result = false;
try {
result = (boolean)intercepterMethod.invoke(object, args); //反射拦截方法
return result;
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
上面代码中提到了IntercepterFactory类,那我们先来看看这个类
在上面的框图中所提到的InteecepterMethodDefination类中有成员的get()和set()方法、IntercepterTargetDefination类有equas()方法
在下面的代码中只写出了addBeforeMap()、getbeforeMethodList()方法,其他的addAfterMap()、addExceptionMap()、getbeforeMethodList()、getbeforeMethodList()与它们相似,这里就不再写出来
public class IntercepterFactory {
private static final Map<IntercepterTargetDefination, List<IntercepterMethodDefination>> beforeMap;
private static final Map<IntercepterTargetDefination, List<IntercepterMethodDefination>> afterMap;
private static final Map<IntercepterTargetDefination, List<IntercepterMethodDefination>> exceptionMap;
static {
beforeMap = new HashMap<>();
afterMap = new HashMap<>();
exceptionMap = new HashMap<>();
}
private void addIntercepterMap(
Map<IntercepterTargetDefination, List<IntercepterMethodDefination>> map,
IntercepterTargetDefination intercepterTarget,
IntercepterMethodDefination intercepterMethod) {
List<Interc