(请观看本人博文 —— 《详解 反射机制》)
动态代理
概述:
- 代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
举例:春季回家买票让人代买- 动态代理:在程序运行过程中,产生的这个对象
而程序运行过程中产生对象,其实就是本人刚才反射讲解的内容,
所以,动态代理其实就是通过反射来生成一个代理
特点:
字节码 随用随创建,随用随加载
作用:
不修改源码的基础上对方法增强
分类:
基于接口的动态代理
基于子类的动态代理
注意:JDK给我们提供的动态代理,只能对接口进行代理.
如何创建代理对象:
使用Proxy类中的newProxyInstance方法
创建代理对象的要求:
被代理类最少实现一个接口,如果没有则不能使用
其实,动态代理,主要应用了两个方法:
- Proxy类中的方法创建动态代理类对象:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
参数:
loader: 类加载器
interfaces: 接口对应的一个Class数组
InvocationHandler: 这个其实就是要代理对象所做的事情的一个类的封装
- 而这个方法,最终会调用InvocationHandler接口的方法:
InvocationHandler Object invoke(Object proxy,Method method,Object[] args)
作用:执行被代理对象的任何接口方法都会经过该方法
参数:
proxy:代理对象的引用
method:当前执行的方法
args:当前执行方法所需的参数
返回值:和被代理对象方法有相同的返回值
那么,现在,本人就来展示下通过这些知识点,来编写一个动态代理小工具,并做下使用展示:
首先是 动态代理小工具:
package edu.youzg.about_reflact.core;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
//获取代理对象的方法
//参数:就是被代理对象(目标对象)
//返回值:代理对象
public static IUserDao getProxy(IUserDao userDao) {
IUserDao obj = (IUserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行目标对象的任何接口方法都会经过该方法
Object result = null;
if (method.getName().equals("delete")) { //这里仅仅对该接口的delete()方法做了增加了几个步骤
System.out.println("权限的校验 "); //增强的代码
result = method.invoke(userDao);//让目标对象中方法执行
System.out.println("记录日志"); //增强的代码
} else {
result = method.invoke(userDao);//让目标对象中方法执行
}
return result;
}
});
return obj; //返回代理对象
}
}
现在,本人来给出一个测试接口:
package edu.youzg.about_reflact.core;
public interface IUserDao {
void insert();
void delete();
void update();
void query();
}
本人再来给出一个测试接口的实现类:
package edu.youzg.about_reflact.core;
public class UserDaoImpl implements IUserDao{
@Override
public void insert() {
System.out.println("添加一个用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void query() {
System.out.println("查询用户");
}
}
现在,本人来给出一个测试类,来展示下这个小工具的使用:
package edu.youzg.about_reflact.core;
import com.sun.deploy.net.proxy.ProxyUtils;
public class Test {
public static void main(String[] args) throws Exception {
IUserDao userDao = new UserDaoImpl();
//我们采用动态代理的模式,在不修改原有代码的情况下,对类中的方法进行增强(增加一些额外功能)
//通过我们写的工具类,来获取一个代理对象
IUserDao proxy = ProxyUtil.getProxy(userDao);
proxy.insert();
System.out.println("----------------------");
proxy.delete();
System.out.println("----------------------");
proxy.update();
System.out.println("----------------------");
proxy.query();
}
}
那么,本人来展示下运行结果:
可以看到,只有删除操作,多了几个步骤。
(本人 反射机制 总集篇博文链接:https:////www.cnblogs.com/codderYouzg/p/12419061.html)