使用动态代理的基本步骤如下:
1、定义代理对象和真实对象的公共接口;(与静态代理步骤相同)
2、真实对象实现公共接口中的方法;(与静态代理步骤相同)
3、定义一个实现了InvocationHandler接口的动态代理类;
4、通过Proxy类的newProxyInstance方法创建代理对象,调用代理对象的方法。
例如下面的例子,有一个学生接口,有登录和注册两种功能,我们想要在不改变原有代码的基础上,增加权限验证和日志记录的功能。这时候就需要使用我们的动态代理模式来实现。
StudentDao接口代码
package com.duhaoyu.动态代理;
/**
* @author duhaoyu
* @date 2020/11/25 9:28
*/
public interface StudentDao {
void login();
void register();
}
StudentDaoImpl实现类代码
package com.duhaoyu.动态代理;
/**
* @author duhaoyu
* @date 2020/11/25 9:29
*/
public class StudentDaoImpl implements StudentDao {
@Override
public void login() {
System.out.println("登录功能");
}
@Override
public void register() {
System.out.println("注册功能");
}
}
写出上面两个类之后,我们就可以测试使用这两个功能了。但是如果我们想要不改变原有代码的基础上,增加功能就需要使用代理模式,来产生一个代理对象。帮我们去做。
使用java原生的接口InvocationHandler ,实现动态代理
package com.duhaoyu.动态代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author duhaoyu
* @date 2020/11/25 9:30
*/
public class MyInvocationHandler implements InvocationHandler {
private Object object;
public MyInvocationHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限验证");
Object res = method.invoke(object,args);
System.out.println("日志记录");
return res;
}
}
测试
package com.duhaoyu.动态代理;
import java.lang.reflect.Proxy;
/**
* @author duhaoyu
* @date 2020/11/25 9:29
*/
public class Test {
public static void main(String[] args) {
StudentDao sd = new StudentDaoImpl();
sd.login();
sd.register();
System.out.println("--------------------");
MyInvocationHandler handler = new MyInvocationHandler(sd);
StudentDao proxy =(StudentDao) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), handler);
proxy.login();
proxy.register();
}
}