07 代理模式
代理:隐藏具体实现,在不修改源代码的基础上,完成对已有功能的扩展
1 静态代理
问题:
- 如果接口中增加了方法,不管此方法是否需要代理,代理类都得重写该方法
- 必须为每一个目标类创建代理类,麻烦且不易维护
因此产生动态代理。
2 动态代理
代理类不需要程序员自己创建,由JDK在内存中,生成一个虚拟的class文件,产生代理类的对象。
2.1 接收动态代理的API
java.lang.reflect.proxy 提供用于创建动态代理类和实例的静态方法。
static Object | newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) |
InvocationHandler 是代理实例的调用处理程序实现的接口。
2.2 动态代理的实现
package com.sxt.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Date;
import com.sxt.dao.UserDAO;
import com.sxt.dao.impl.UserDAOImpl;
public class ProxyUtils {
public static Object getProxyInstance() {
return Proxy.newProxyInstance(Proxy.class.getClassLoader(),
new Class[] { UserDAO.class }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 需要扩展的功能
System.out.println(new Date() + " "
+ method.getName() + "被执行,传入的实参为:"
+ Arrays.toString(args));
// 放行,调用目标对象的方法 obj.method(args)
Object rv = method.invoke(new UserDAOImpl(), args);
// 将目标方法的返回值,进行返回,代理对象调用方法的时候,才能拿到返回值
return rv;
}
});
}
}