代理模式详解
代理模式
真实生活中有一种房屋中介是这样的,租客根本就不知道房东是谁,一切签合同、交租金、交钥匙等操作都直接和中介公司发生。我们把这种模式称之为代理模式。
代理模式:客户端直接使用的都是代理对象,不知道目标对象是谁,此时代理对象可以在客户端和目标对象之间起到中介的作用。
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();
}
}
测试结果