目录
一、基础概念
代理模式:为对象提供一种代理,以控制对这个对象的访问。
图中,一个接口Subject,真正的实现类RealSuject,代理类Proxy也继承这个接口,并引用了真正的实体类,可以通过实现接口下面的方法,来对方法进行修改,客户端直接调用代理类来实现想在方法中添加的功能。
二、代理模式分为动态代理和静态代理:
动态代理:在程序运行的时候,类使用的时候进行调用,不用的时候不创建
静态代理:在类加载使用之前,在程序运行的时候就已经创建好
三、应用场景:
在不借助spring框架下,需要对数据进行增删改操作的方法,总是需要自己调用事物,手动开启关闭回滚事物。这些事情可以通过动态代理来实现。
package com.bjpowernode.drp.util;
/**
* 采用动态代理封装事务
* @author Administrator
*
*/
public class TransactionHandler implements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Connection conn = null;
Object ret = null;
try {
//从ThreadLocal中取得Connection
conn = ConnectionManager.getConnection();
if (method.getName().startsWith("add") ||
method.getName().startsWith("del") ||
method.getName().startsWith("modify")) {
//手动控制事务提交
ConnectionManager.beginTransaction(conn);
}
//调用目标对象的业务逻辑方法
ret = method.invoke(targetObject, args);
if (!conn.getAutoCommit()) {
//提交事务
ConnectionManager.commitTransaction(conn);
}
}catch(ApplicationException e) {
//回滚事务
ConnectionManager.rollbackTransaction(conn);
throw e;
}catch(Exception e) {
e.printStackTrace();
if (e instanceof InvocationTargetException) {
InvocationTargetException ete = (InvocationTargetException)e;
throw ete.getTargetException();
}
//回滚事务
ConnectionManager.rollbackTransaction(conn);
throw new ApplicationException("操作失败!");
}finally {
ConnectionManager.closeConnection();
}
return ret;
}
}
动态代理方法:
Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口、目标接口的类加载器以及InvocationHandler便可为目标接口生成代理类及代理对象。
传入目标对象的加载器:targetObject.getClass().getClassLoader()
该目标对象的接口类:targetObject.getClass().getInterfaces()
调用当前对象:this(目的是调用invoke方法)
小结:
我们不用任何框架的前提下,在前端的请求已经发送过来后需要调用业务逻辑层,并通过抽象工厂+反射来实现需要的业务逻辑层类的实例化的时候,可以插入这个动态代理的类,来对当前实例化后的对象进行动态代理。
比如例子中的,链接数据库,对事物的手动控制。动态代理是spring框架中AOP基础实现用到的模式。