Spring系列之六:AOP的代理详解

Aop是面向切片的编程,首先先用图解释AOP的编程

这是没有用aop的情况,代码中存在大量的重复的代码:

Spring系列之六:AOP的代理详解_第1张图片


使用aop就是采用一个切片,对封装好的程序进行切开,减少重复的代码,对重复的代码进行复用:

Spring系列之六:AOP的代理详解_第2张图片

那么如何实现这种aop的切片编程了?就是使用动态代理的方式,为方法增加方法,现在就讲一讲代理的原理:

代理就相当于处于一个中间层,当一个对象不能调用另一个对象的方法时候,可以通过代理进行调用。

首先是静态代理:

        静态代理相当于首先定义了一个接口,接口中有个方法,出于不同的需要,我们有很多子类实现了这个接口并重写了这个接口中的方法(被代理类)。静态代理处于中间层不断调用代理类。

下面给出实现代理的源代码:

1.接口的实现

/**
 * Subject接口的实现
 */
public interface Subject {
    void visit();
}

2.产生被代理类

/**
 * Subject接口的实现
 */
public class SubjectImpl implements Subject {
    public void visit() {
        System.out.println("SubjectImpl!");
    }
}

3.中间层代理类

public class ProxySubject implements Subject {
    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    public void visit() {
        subject.visit();
    }
}

4.使用代理类

public class Client {
    public static void main(String[] args) {
        ProxySubject subject=new ProxySubject(new SubjectImpl());
        subject.visit();
    }
}

由此可以看到,我们对接口中的方法进行了扩充。aop中使用代理就是对方法进行扩充


现在讲一讲动态代理:

    由上面的例子可以看出,你对接口中的方法进行扩充的时候,你每次都要进行新建一个类,给代理类进行调用,以后程序越写越多就会十分麻烦,那这个时候就要用到动态代理,就在产生的被代理类上进行扩充,而不需要频繁的进行建类

下面给出动态代理的实现源代码:

1.接口类

/**
 * Subject接口的实现
 */
public interface Subject {
    void visit();
}

2.被代理类

/**
 * Subject接口的实现
 */
public class SubjectImpl implements Subject {
    public void visit() {
        System.out.println("SubjectImpl!");
    }
}
3.使用handler对被代理类进行扩充

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class Handler implements InvocationHandler {
    private Object target;

    public Handler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始事务!");
        method.invoke(target,args);
        System.out.println("事务结束!");
        return null;
    }
}

4.调用代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args)  {
        SubjectImpl subjectImpl=new SubjectImpl();
        InvocationHandler handler=new Handler(subjectImpl);
        Subject subject = (Subject) Proxy.newProxyInstance(subjectImpl.getClass().getClassLoader(),
                subjectImpl.getClass().getInterfaces(),
                handler);
        subject.visit();
    }
}

Proxy.newProxyInstance用于产生参数

第一个参数:ClassLoader loader:它是类加载器类型

第二个参数:Class[] interfaces:指定newProxyInstance()方法返回的对象要实现哪些接口,没错,可以指定多个接口

第三个参数:handler主要就是对方法增加内容


aop面向切片编程就是这样为方法增加内容,aop主要使用Cglin代理和动态代理,动态代理传入的是个接口,而cglib闯入是对象,Spirng自行选择该使用何种方法。总之是为了在原基础上增加内容。





你可能感兴趣的:(Spring)