代理模式

AOP实现原理是基于动态代理实现的。

代理模式是一种软件设计模式。其核心思想是通过访问代理对象去操作被代理的对象。代理对象与被代理对象有同样的方法接口,且对被代理的对象的方法进行了扩展。从而实现不修改被代理对象的情况下,实现被代理对象业务逻辑的更改。

代理模式又分为静态代理和动态代理两种。

我的目录为:

一、静态代理是在代码编译是就确定了被代理对象。

实现方式:

1) 代理对象与被代理对象实现同样的接口==>保证行为一致与类型一致

2) 代理对象持有一个被代理对象。==>代理对象能够调用被代理对象的逻辑

a、Star.java文件

/**
 * 代理类与被代理类实现统一的接口
 */
public interface Star {
    void actor();
    void sing();
}

b、被代理对象LiuDenHua实现接口中的方法;

public class LiuDenHua implements Star{
    @Override
    public void actor() {
        System.out.println("刘德华演戏");
    }

    @Override
    public void sing() {
        System.out.println("刘德华唱歌");
    }
}

c、代理类去实现接口,并添加一些其他的业务方法;

/**
 * 代理类
 */
public class StarProxy implements Star{
    //持有一个被代理对象
    private Star liuDenHua;//接口
    //private LiuDenHua liuDenHua;
    public StarProxy(Star liuDenHua) {
        this.liuDenHua = liuDenHua;
    }
    @Override
    public void actor() {
        System.out.println("经纪人谈合同");
        liuDenHua.actor();
        System.out.println("经纪人收钱");
    }
    @Override
    public void sing() {
        System.out.println("经纪人联系场地");
        liuDenHua.sing();
        System.out.println("经纪人收钱");
    }
}

d、写一个测试文件,测试是否成功;

public class Test {
    public static void main(String[] args) {
        //创建被代理对象
        Star liuDenHua = new LiuDenHua();
        //创建代理对象,并传入被代理对象
        Star starProxy = new StarProxy(liuDenHua);
// starProxy.actor();
// starProxy.sing();
show(starProxy); }
public static void show(Star star){
star.actor();
star.sing();
}
}

测试结果为:

二、动态代理:在代码运行期间才加载被代理的类,动态生成代理对象。

Spring 动态代理有两种实现机制
1)JDK动态代理:jdk动态代理有java自身提供,其利用反射机制生成一个实现代理接口的匿名类(代理类)。Spring默认的方式。

a、 被代理的类需要实现接口。

b、接口

c、被代理类

d、生成代理对象的类 (实现InvocationHandler接口)

/**
 * 动态代理
 * jdk代理
 * 实现InvocationHandler
 */
public class JDKDynamicProxy implements InvocationHandler {
    //持有一个被代理对象
    private Object object;

    /**
     * 根据被代理对象生成代理类
     * @param targetObject  被代理的对象
     * @return
     */
    public Object getInstance(Object targetObject){
        //给被代理对象赋值
        this.object=targetObject;
        //生成代理对象
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//获取类加载器
                targetObject.getClass().getInterfaces(),//获取被代理对象实现的接口
                this//动态代理方法执行时,会调用该对象的invoke方法
        );
    }

    /**
     * 调用代理对象的方法
     * @param proxy 代理对象
     * @param method  调用的方法
     * @param args  调用方法传递的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开启事务");
        //调用被代理对象的方法
        Object invoke = method.invoke(object, args);
        System.out.println("提交事务");
        return invoke;
    }
}

测试:

public class Test {

    public static void main(String[] args) {
        //被代理类
        LiuDenHua liuDenHua = new LiuDenHua();
        JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy();
        //动态生成代理类对象
        Star instance = (Star) jdkDynamicProxy.getInstance(liuDenHua);
        instance.sing();
        instance.actor();
    }
}

2)cglib动态代理:通过java字节码编辑技术,生成一个被代理对象的一个子类(代理类)。来实现代理效果。

a.        被代理的类不需要实现接口

b.       被代理类(普通类)

c.        生成代理对象类(实现MethodInterceptor接口)

/**
 * cglib 动态代理
 */
public class CglibDynamicProxy implements MethodInterceptor {
    /**
     * 生成代理对象的方法
     * @param target
     * @return
     */
    public Object getProxy(Object target){
        return Enhancer.create(target.getClass(),this);
    }

    /**
     *
     * @param o  被代理的对象
     * @param method  被代理的方法
     * @param objects  方法参数
     * @param methodProxy  代理方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("前置处理");
        //调用被代理对象的方法
        Object invoke = methodProxy.invokeSuper(o, objects);
        System.out.println("后置处理");
        return null;
    }
}

另外建一个Player.java文件:

/**
 * 普通类
 */
public class Player {

    public void play(){
        System.out.println("玩的很开心");
    }
}

测试:

 //cglib动态代理
        //创建被代理对象
        Player player = new Player();
        //创建生产动态代理对象的对象
        CglibDynamicProxy cglibDynamicProxy = new CglibDynamicProxy();
        //生产代理对象
        Player proxy = (Player) cglibDynamicProxy.getProxy(player);
        proxy.play();
原文地址:https://www.cnblogs.com/xie-qi/p/13040736.html