因为这个AOP--面向切面编程是基于动态代理模式的,所以,要想搞清楚这个AOP,就必须得先了解下, 什么是代理模式什么又是动态代理模式动态代理模式的2种实现方式。

现在假设,你已经可以看得懂动态代理模式的Java代码例子。把aop概念里面的专业术语对应到实际代码中去。

下面是cglib实现的动态代理模式的Java代码

package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy; 
 
/** 
 * 被代理的类 
 * 目标对象类 
 */ 
public class TargetObject { 
 
    /** 
     * 目标方法(即目标操作) 
     */ 
    public void business() { 
        System.out.println("business"); 
    } 
 
} 

package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy; 
 
import net.sf.cglib.proxy.Enhancer; 
import net.sf.cglib.proxy.MethodInterceptor; 
import net.sf.cglib.proxy.MethodProxy; 
 
import java.lang.reflect.Method; 
 
/** 
 * 动态代理-拦截器 
 * <p> 
 * Created by lxk on 2016/11/25 
 */ 
public class MyInterceptor implements MethodInterceptor { 
    private Object target;//目标类 
 
    public MyInterceptor(Object target) { 
        this.target = target; 
    } 
 
    /** 
     * 返回代理对象 
     * 具体实现,暂时先不追究。 
     */ 
    public Object createProxy() { 
        Enhancer enhancer = new Enhancer(); 
        enhancer.setCallback(this);//回调函数  拦截器 
        //设置代理对象的父类,可以看到代理对象是目标对象的子类。所以这个接口类就可以省略了。 
        enhancer.setSuperclass(this.target.getClass()); 
        return enhancer.create(); 
    } 
 
    /** 
     * args 目标方法的参数 
     * method 目标方法 
     */ 
    @Override 
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 
        if(true){//不要在意这为什么是恒成立的条件语句,为的是说明一个aop的概念:切入点。 
            System.out.println("aaaaa");//切面方法a(); 
            //。。。 
            method.invoke(this.target, objects);//调用目标类的目标方法 
            //。。。 
            System.out.println("bbbbb");//切面方法f(); 
        } 
        return null; 
    } 
} 

package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy; 
 
public class MainTest { 
    public static void main(String[] args) { 
        //目标对象 
        TargetObject target = new TargetObject(); 
        //拦截器 
        MyInterceptor myInterceptor = new MyInterceptor(target); 
        //代理对象,调用cglib系统方法自动生成 
        //注意:代理类是目标类的子类。 
        TargetObject proxyObj = (TargetObject) myInterceptor.createProxy(); 
        proxyObj.business(); 
    } 
} 

上面代码,看完之后,就来 对应AOP里面的各个概念到实际代码里面去


图上说了5个术语。加上下面的织入,也就是6个啦。

再加上代理对象,这个就比较简单了,测试代码有写注释啦。那么就是一共7个啦。

唯一漏掉的就是“引入”,这个是系统自己实现的,我们就没必要去深究了。


注意理解以下几个概念:
代理对象的方法 = 目标对象的目标方法 + 所有切面的通知。
织入
形成代理对象的方法的过程

通知:实际上就是切面中的方法

切入点的理解:只有符合切入点的目标方法,才能加载通知。也就是调用切面的通知(方法)啦,看代码也就是说,切入点是控制代理对象内部的切面方法和目标对象的目标方法是否执行的条件。切面可以不止是一个。每个切面里面的通知即切面方法也是可以有很多的。
连接点的理解:所谓连接点,也就是目标对象或者代理对象之中的方法。为什么说2个都 可以呢?因为如果是jdk实现的动态代理的话,那么目标对象和代理对象要实现共同的接口,如果是cglib实现的动态代理的话,那么代理对象类是目标对象类的子类。都是一个方法啦。所以这么理解就OK的啦。


现在就简单的先了解下AOP的几个概念术语。直接看文档的描述,表示真不是分分钟就可以看得懂的,现在结合代码实例,然后来说明概念就好理解多啦。


下面是摘自文档spring.chm里面的关于AOP的关键术语的描述:请欣赏,大学老师讲课。

切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式)或者基于@Aspect注解的方式来实现。 

连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。

通知(Advice):在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等不同类型的通知(通知的类型将在后面部分进行讨论)。许多AOP框架(包括Spring)都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。 

切入点(Pointcut):匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。 

引入(Introduction):用来给一个类型声明额外的方法或属性(也被称为连接类型声明(inter-type declaration))。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用引入来使一个bean实现IsModified接口,以便简化缓存机制。 

目标对象(Target Object): 被一个或者多个切面所通知的对象。也被称做被通知(advised)对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。 

AOP代理(AOP Proxy)AOP框架创建的对象,用来实现切面契约(例如通知方法执行等等)。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 

织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。 


上面的东西就算背会了,有卵用啊。就算你复制粘贴的到处都是,有卵用啊。

在看了上面的实例代码之后,这下子知道所谓的切面是什么意思了吧。后面再看看spring框架里面到底是怎么在使用这个aop的吧。后话了。


所以:我原来的那张图就可以做如下的修改咯。







评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!