动态理解
要想理解理解动态代理,首先要知道他的概念是什么?
要素
代理模式涉及到四个要素:调用者、代理对象、目标对象、抽象对象。
概述
对方法进行覆盖重写时,使用继承的前提是首先需要一个实现类,但是我们只有接口或者抽象对象时如何能够覆盖重写方法呢。这时我们可以通过动态代理的方式来实现。
动态代理就是在程序运行的过程中,动态创建出代理对象。
那么什么是动态呢?
在这里提一下代理模式
代理对象可以在调用者和目标对象之间起到中介的作用。 代理对象可以对目标对象的功能进行增强。
代理模式例:
//这里是一个简单的接口
public interface CURD
{
public void add();
public void update();
public void delete();
}
//简单的实现类
public class UserDao implements CURD
{
@Override
public void add()
{
System.out.println("add开始增强");
}
@Override
public void update()
{
System.out.println("update开始增强");
}
@Override
public void delete()
{
System.out.println("delete开始增强");
}
}
//test类
public class TestUserDao
{
@Test
public void test01() throws Exception
{
// 直接调用 目标类对象方法
UserDao userDao = new UserDao();
userDao.add();//输出的结果为add开始增强
userDao.update();//输出的结果为update开始增强
userDao.delete();//输出的结果为delete开始增强
}
}
/**
UserDao在这里就起到了一个代理的作用
*/
这个例子非常简单,相信初学者也可以看懂
那么什么是动态代理呢?
其实动态代理就是在程序运行的过程中,动态创建出代理对象,在不改变目标类的代码情况下,代理对象可以对目标对象的功能进行增强。
相关API
-
Proxy
类static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
作用:生成实现指定接口的代理对象 -
InvocationHandler
接口Object invoke(Object proxy, Method method, Object[] args)
作用:在这个方法中实现对真实方法的增强
例:
//这里我用一下静态代理的例子,方便对比
//这里是一个简单的接口
public interface CURD
{
public void add();
public void update();
public void delete();
}
//简单的实现类
public class UserDao implements CURD
{
@Override
public void add()
{
System.out.println("add开始增强");
}
@Override
public void update()
{
System.out.println("update开始增强");
}
@Override
public void delete()
{
System.out.println("delete开始增强");
}
}
//============================================================
//test类
public class TestUserDao
{
@Test
public void test01() throws Exception
{
// 使用动态代理技术 对此目标类所有方法增强
// 使用JDK提供的 proxy工具类
CURD userProxy = (CURD) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), new Class[]{CURD.class}, new InvocationHandler()
{
/*
* 调用者----代理对象 --- 所有的方法都会先进入(invoke)
*
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("开启事务");
// 调用目标类原有的方法
/*
* 参数一:目标类对象
* 参数二:args
* */
Object obj = method.invoke(userDao, args);
System.out.println("提交事务");
// 把目标类的返回值给调用者
return obj;
}
});
userProxy.add();
userProxy.update();
userProxy.delete();
}
}
小结
Proxy.newProxyInstance()方法的本质 创建了代理对象,代理对象实现了传入的接口。
代理模式的好处就是在不改变目标类的代码情况下,代理对象可以对目标对象的功能进行增强 。