静态代理的缺点:
- 代理类中的添加项需要重新书写多次
- 新增加被代理类时,需要重新写代理类的添加项
动态代理的实现步骤:
- 编写一个代理工作处理器–代理者要替被代理者做XXX事
要求: 必须实现InvocationHandler - 创建代理者的对象
要用到:Proxy工具类,里面有一个方法,可以直接创建代理类的对象
代理类是在JVM中自动生成的一个类型
newProxyInstance三个参数:
- 类加载器:加载类的工具类,通过这个类的class 对象,就可以创关键
- 被代理者实现的主题接口们
- 代理者要替被代理者的工作的处理器
public class TestDynamicProxy{
public static void main(String[] args) {
//先获取被代理者的class对象
Class c = MySqlVersion.class;
//2.获取他的类加载器对象
ClassLoader loader = c.getClassLoader();
//3.创建处理工作的处理器
MyInvocationHandler my = new MyInvocationHandler(true, new MySqlVersion());
Object proxyInstance = Proxy.newProxyInstance(loader, c.getInterfaces(), my);
//转型
IGoods iGoods = (IGoods) proxyInstance;
iGoods.add();
iGoods.delete();
iGoods.list();
iGoods.update();
//-------------------------------------------
Class uc = UserManager.class;
MyInvocationHandler my2 = new MyInvocationHandler(true,new UserManager());
IUser iu = (IUser) Proxy.newProxyInstance(uc.getClassLoader(), uc.getInterfaces(), my2);
iu.add();
iu.update();
iu.delete();
iu.list();
}
}
class MyInvocationHandler implements InvocationHandler{
private boolean flag ;
private Object target;
//通过构造器将需要的参数传进来
public MyInvocationHandler(boolean flag, Object target) {
super();
this.flag = flag;
this.target = target;
}
//代理者要替被代理者做的事写在这里:
/*
invoke的三个参数的作用:
1.Object proxy:代理对象
2.Method metho:被代理者要执的方法
3.Object[] args:要传给被代理者执行的方法的是参列表
这个方法不是程序员手动改调用的,是在别的类中帮我们调用的
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;//被代理者要执行的方法的返回值,若是void,自动给返回null
if(flag){
System.out.println("开始 记录日志,获取开始时间,权限验证....");
result =method.invoke(target,args);
System.out.println("结束 记录日志, 获取结束时间, 权限验证...");
}else{
result =method.invoke(target, args);
}
return result;
}
}
//新添一个代理接口
interface IUser{
void add();
void delete();
void update();
void list();
}
//新被代理类
class UserManager implements IUser{
@Override
public void add() {
System.out.println("用户添加..");
}
@Override
public void delete() {
System.out.println("用户删除...");
}
@Override
public void update() {
System.out.println("用户修改...");
}
@Override
public void list() {
System.out.println("用户查询...");
}
}
//-----------------------------------------
//代理类接口--主题接口
interface IGoods{
void add();
void delete();
void update();
void list();
}
//被代理者们
class MySqlVersion implements IGoods{
@Override
public void add() {
System.out.println("mysql版的添加商品");
}
@Override
public void delete() {
System.out.println("mysql的删除商品");
}
@Override
public void update() {
System.out.println("mysql的修改商品");
}
@Override
public void list() {
System.out.println("mysql的查询商品");
}
}
class OracleVersion implements IGoods{
@Override
public void add() {
System.out.println("oracle的添加商品");
}
@Override
public void delete() {
System.out.println("oracle的删除商品");
}
@Override
public void update() {
System.out.println("oracle的更新商品");
}
@Override
public void list() {
System.out.println("oracle的查询商品");
}
}