本篇博文的目的
模拟Spring实现控制反转,以及实现某个方法的前置、后置和异常拦截,并把拦截器做成拦截器链。
涉及的编程思想(IoC、AOP)
刚开始没接触这两个概念的时候我也曾在网上阅读一些有关IoC、AOP的东西,但我发现里面夹杂着许多别的名词,十分生涩难懂;那么在这篇博文中我会结合自己的理解,用通俗的语言描述IoC、AOP。
控制反转(IoC)
无一例外,在使用某一个类时有两个步骤:一:声明这个类(为这个类分配指针),二:执行无参构造(为这个指针增加实体框架),再给里面的成员赋值(给实体框架里填充真实的值),然后才能用new出来的对象“点”它的方法;
而控制反转就是把执行无参构造(加入到Bean工厂)、给成员赋值(即注入,且一般只给类类型注入)的任务交给了工具,让工具执行一个增强版构造方法,所以用户在使用时就可以直接用声明的对象(即指针)“点”这个类的方法对这个类进行使用。
下文中我会讲解增强版构造方法到底增强了什么,怎么增强的?
面向切面编程(AOP)
这个名词语义性很强,我们在编程时,往往会碰到使用jar包的、或者不想在原类中进行更改,但是却不得不在这个类的基础上再进行操作的时候;这个时候面向切面编程就展现出它的优势了,首先给这个类生成代理对象,用代理对象将需要二次加工的方法拦下来形成一个切面,在这个切面上对其操作;它的好处是不用修改原类就可以对其进行操作,降低了代码的耦合度。
图解编程思路
核心代码
拦截器相关代码
IntercepterFactory类:将拦截器链装进来
成员
private static final Map<IntercepterTargetDefinition, List<IntercepterMethodDefinition>> beforeMap;
private static final Map<IntercepterTargetDefinition, List<IntercepterMethodDefinition>> afterMap;
private static final Map<IntercepterTargetDefinition, List<IntercepterMethodDefinition>> exceptionMap;
方法(以BeforeIntercepter为例)
protected void addBeforeIntercepter(IntercepterTargetDefinition intertarget,
IntercepterMethodDefinition intercepter) {
addInterceper(beforeMap, intertarget, intercepter);
}
private void addInterceper(Map<IntercepterTargetDefinition, List<IntercepterMethodDefinition>> interMap,
IntercepterTargetDefinition intertarget, IntercepterMethodDefinition intercepter) {
List<IntercepterMethodDefinition> interList = interMap.get(intertarget);
if (interList == null) {
synchronized (IntercepterFactory.class) {
if (interList == null) {
interList = new ArrayList<>();
interMap.put(intertarget, interList);
}
}
interList.add(intercepter);
}
}
有关注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Before {
Class<?> klass();
String method();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface After {
Class<?> klass();
String method();
Class<?>[] parameters();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DoException {
Class<?> klass();
String method();
}
IntercepterScanner类:扫描出来拦截器,装到IntercepterFactory中
(以下包扫描用的工具也是自己编写的,有时间会写相关博文)