动态代理:
代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
动态代理:在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理。
在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。
JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib
Proxy类中的方法创建动态代理类对象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
最终会调用InvocationHandler的方法
Object invoke(Object proxy,Method method,Object[] args)
下面我们来举一个列子来看一下如何写动态代理:
首先创建一个接口:
public interface UserDao {
public void add();
public void delete();
public void update();
public void find();
}
创建一个接口的实现类:UserDaoImpl
public class UserDaoImpl implements UserDao{
@Override
public void add() {
// TODO Auto-generated method stub
System.out.println("添加功能");
}
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("删除功能");
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("更新功能");
}
@Override
public void find() {
// TODO Auto-generated method stub
System.out.println("查询功能");
}
}
接下来就是重点,创建我们的InvocationHandler:
public class MyInvocationHandler implements InvocationHandler {
private Object target; //目标对象(准备对谁做代理)
public MyInvocationHandler(Object target) {
// TODO Auto-generated constructor stub
this.target = target;
}
//返回的是动态代理对象,真正的操作还是靠基本对象
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("权限校验");
Object object = method.invoke(target, args);
System.out.println("日志记录");
return object; //返回的是代理对象
}
}
测试类:
public class Text {
public static void main(String[] args) {
//Proxy中有个方法可以创建一个动态代理对象
UserDao userDao = new UserDaoImpl();
//准备对userDao对象做一个代理
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(userDao);
UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), myInvocationHandler);
proxy.add();
}
}
总结一下:
1.首先我们明确jdk动态代理只面对接口,所以我们创建了接口UserDao
2.然后我们创建了接口实现类:UserDaoImpl。来实现接口里面的方法。
3.最重要的一步就是创建InvocationHandler对象,既然需要InvocationHandler对象。我们就先创建一个InvocationHandler类,实现InvocationHandler接口,重写里面的invoke方法。
在这个类里我们要创建一个Object对象,这个对象就是我们的目标对象,即准备对谁做代理。
在invoke方法中有三个参数,第一个是Object proxy这是一个代理对象,Method method 这是执行的方法,args是方法的参数。
在这个方法里我们要实现除啦想要目标对象实现的方法外的其余方法,例如,权限验证,日志管理等。这个方法返回的对象即时代理对象。