Spring -- 4.0

时间:2014-07-22 23:07:55   收藏:0   阅读:339

一些Spring AOP的基础

AOP的应用场合是受限的,一般只适用于那些具有横切逻辑的场合:如性能监测、访问控制、事物管理和日志记录。

我很认可书中的这么一个观点(横向和纵向的观点),这个观点也很好的帮助我们理解什么是AOP的思想:按照软件重构的思想,如果多个类中出现相同的代码,我们应该考虑定义一个它们共同使用的父类,将这些公用的代码提取到父类中,通过继承减少重复的代码。但是像事务管理、日志记录我们无法通过抽象父类的方式消除重复性的横切代码,这些横切逻辑的代码存在业务方法中,我们不能把它抽象到父类中。AOP通过横向抽取机制为这类无法通过纵向继承体系抽取重复性代码的场合提供了解决方案。

AOP把分散在各个业务逻辑代码中的共同代码通过横向切割的方式抽取到一个个独立的模块中,还业务逻辑一个清新的世界。

AOP就是要把这些独立的横切逻辑编织到业务逻辑代码中。

AOP的术语

AOP的工作重心就是如何把增强逻辑应用到目标对象的连接点上,这里包括两个工作:第一,如何通过切点定位到连接点;第二,如何在增强中编写切面代码。

学习实际上就是接触和理解新的概念和事物的过程,如果你对一个新领域的概念很清楚了,那也说明你已经学习的差不多了。

AOP的这几个概念,以前一直模模糊糊的,现在感觉到清楚了很多。

AOP的实现有

  1. AspectJ
  2. JBoss AOP
  3. Spring AOP

 Spring AOP使用纯Java实现,不需要专门的编译器和载入器,它在运行期通过代理方式向目标类织入代码增强。
 它有两种代理机制:一种是基于JDK的动态代理;另一种是一语CGLib的动态代理。之所以需要两种代理机制,很大程度上因为JDK本身只提供接口的代理(代理类和原类实现同一接口)而不支持类的代理(代理类为原类的子类)。

JDK动态代理

JDK代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。

InvocationHandler是一个接口,可以通过实现改接口定义横切逻辑,并通过反射机制调用目标类的代码,动态的将横切逻辑和业务逻辑编织在一起。

Proxy是利用InvocationHandler动态的创建一个符合某一接口的实例,生成的目标类的代理对象,书上写了一个例子,我简化了一下(好懒有木有,本来就很简单了):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class PerformanceHandler implements InvocationHandler {
     
    private Object target;//目标对象,业务类。
    public PerformanceHandler(Object target){
        this.target = target;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("======可以把这里认为是织入的代码(横切逻辑),加在方法执行前=======");
        //通过反射方法调用业务类的目标方法。
        Object obj = method.invoke(target, args);
        System.out.println("======可以把这里认为是织入的代码(横切逻辑),加在方法执行后=======");
        return obj;
    }
} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ProxyTest1 {
 
    public static void main(String[] args) {
        IForumService target = new ForumServiceImpl();//希望被代理的目标类。
        PerformanceHandler handler = new PerformanceHandler(target);
        //根据编织了目标业务类逻辑和横切逻辑的InvocationHandler实例创建代理实例。
        IForumService proxy = (IForumService) Proxy.newProxyInstance(target
                .getClass().getClassLoader(),
                target.getClass().getInterfaces(), handler);   
        proxy.removeForum(100);
        System.out.println();
        proxy.removeTopic(999);
    }
}<br>//执行结果

======可以把这里认为是织入的代码(横切逻辑),加在方法执行前=======
========模拟删除Forum记录:100============
======可以把这里认为是织入的代码(横切逻辑),加在方法执行后=======

======可以把这里认为是织入的代码(横切逻辑),加在方法执行前=======
========模拟删除Topic记录:999============
======可以把这里认为是织入的代码(横切逻辑),加在方法执行后=======

  代码可以运行。这里代理类对ForumServiceImpl中的所有方法进行代理(编织增强逻辑)。

后续。

 

Spring -- 4.0,码迷,mamicode.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!