1.什么是动态代理?
答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。
2.为什么使用动态代理?
答:因为动态代理可以对请求进行任何处理
3.使用它有哪些好处?
答:因为动态代理可以对请求进行任何处理
4.哪些地方需要动态代理?
答:不允许直接访问某些类;对访问要做特殊处理等
目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现
以下为模拟案例,通过动态代理实现在方法调用前后向控制台输出两句字符串
下面是testPorject的结构
首先定义一个DAO接口
IUserDao
package org.zhy.demo.proxy.Dao;
public interface IUserDao {
public void addUser(String name, int age);
}
DAO接口只定义了一个addUser的方法,DAO的实现类负责实现对数据库的添加操作
IUserDaoImpl
package org.zhy.demo.proxy.Dao.Impl;
import org.zhy.demo.proxy.Dao.IUserDao;
public class IUserDaoImpl implements IUserDao {
/**
* 这里模拟数据库操作 只打印信息
*/
@Override
public void addUser(String name, int age) {
System.out.println("开始添加user");
System.out.println("NAME:"+name);
System.out.println("AGE:"+age);
System.out.println("user添加完成");
}
}
添加一个新的类:MyInvocationHandler
package org.zhy.demo.proxy.invocation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 代理类,需要实现InvocationHandler接口
* @author Administrator
*
*/
public class MyInvocationHandler implements InvocationHandler {
//定义一个私有变量,被代理的对象
private Object setter;
public Object getSetter() {
return setter;
}
public void setSetter(Object setter) {
this.setter = setter;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.startProxy(); //在方法执行之前执行代理方法
method.invoke(setter, args); //执行被代理对象的方法
this.endProxy();//同时 在方法结束的时候也执行一下代理方法
return null;
}
/**
* 定义两个代理方法
*/
private void startProxy() {
System.out.println("开始执行代理方法");
}
private void endProxy() {
System.out.println("执行代理方法结束");
}
}
下面是具体实现:
UserService
package org.zhy.demo.proxy.service;
import java.lang.reflect.Proxy;
import org.zhy.demo.proxy.Dao.IUserDao;
import org.zhy.demo.proxy.Dao.Impl.IUserDaoImpl;
import org.zhy.demo.proxy.invocation.MyInvocationHandler;
public class UserService {
public static void main(String[] args) {
IUserDao userDao = new IUserDaoImpl(); //实例化一个userDao
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(); //实例化自己的代理类
myInvocationHandler.setSetter(userDao); //被代理的对象
IUserDao dao = (IUserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), myInvocationHandler); //定义一个新的代理
dao.addUser("张三", 23); //执行dao的方法
}
}
执行结果