代理模式详解

代理模式

真实生活中有一种房屋中介是这样的,租客根本就不知道房东是谁,一切签合同、交租金、交钥匙等操作都直接和中介公司发生。我们把这种模式称之为代理模式。

代理模式:客户端直接使用的都是代理对象,不知道目标对象是谁,此时代理对象可以在客户端和目标对象之间起到中介的作用。

1、代理对象完全包含目标对象,客户端使用的都是代理对象的方法,和目标对象没有直接关系;

2、代理模式的职责:把不是目标对象该做的事情从目标对象上撇开——职责清晰;

静态代理:在程序运行前就已经存在代理类的字节码文件,代理对象和目标对象的关系在运行前就确定了。

动态代理:动态代理类是在程序运行期间由JVM通过反射等机制动态的生成的,所以不存在代理类的字节码文件。代理对象和真实对象的关系是在程序运行事情才确定的。

静态代理实例

项目目录结构

代理模式详解

UserService.java

代理模式详解

UserServiceImpl.java(目标对象)

代理模式详解

代理类需要添加的事务TransactionManager.java:

代理模式详解

UserServiceProxy.java(代理类)

代理模式详解

测试类

代理模式详解

测试结果

代理模式详解

JDK动态代理实例

JDK动态代理是代理模式的一种实现方式,只能代理接口。

使用步骤

1、 新建一个接口

2、 为接口创建一个实现类

3、 创建代理类

4、 测试

本测试除了创建代理类的文件跟测试文件跟上一个测试不同之外,其余都相同.

JDKProxy.java(创建代理类)

package com.xiongluoluo.service.impl;

import com.xiongluoluo.tx.TransactionManager;

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

/**
 * Created by Administrator on 2020/1/1 0001.
 */
public class JDKProxy{
    private Object target;
    private TransactionManager tx=new TransactionManager();

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

    /*定义泛型方法,获取代理类*/
    public <T>T getProxy(){
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = null;
                        try{
                            tx.begin();
                            result = method.invoke(target, args);
                            tx.commit();
                            tx.close();
                            return result;
                        }catch (Exception e){
                            e.printStackTrace();
                            tx.rollback();
                        }
                        return result;
                    }
                });
          }

    }

 

测试类ProxyTest

package com.xiongluoluo.test;

import com.xiongluoluo.service.UserService;
import com.xiongluoluo.service.impl.JDKProxy;
import com.xiongluoluo.service.impl.UserServiceImpl;
import org.junit.Test;

/**
 * Created by Administrator on 2020/1/1 0001.
 */

public class ProxyTest {
    @Test
    public void test(){
        UserService userService = new UserServiceImpl();
        JDKProxy jdkProxy = new JDKProxy(userService);
        UserService proxy = jdkProxy.getProxy();
        proxy.saveUser();
    }
}

 

测试结果

代理模式详解