一、什么是动态代理?
我的理解而言,代理有静态代理和动态代理。静态代理类一般是与被代理类实现同一个接口,并且代理类拥有被代理类的实例,为被代理被增强方法功能;动态代理是在运行过程中动态生成代理对象,增强被代理类的方法功能,或者是代理接口,动态生成接口实现类,实现接口功能。
二、动态代理的使用
1.接口如下:
public interface ProxyInf {
void testProxy(String words);
}
2.实现类如下:
public class ProxyImpl implements ProxyInf {
@Override
public void testProxy(String words) {
System.out.println("实现");
}
}
3.代理类如下:
public class ProxyGenerate implements InvocationHandler {
Object o =null;
//生成代理对象,这里直接传入接口类型,使用new Class[]{}
//如果传入接口实例,则用对象接收,t.getClass().getInterfaces(),并在下面方法中使用method.invoke(对象,方法参数)来调用实例方法
public <T> T newProxyInstance(Class<T> clazz){
try {
o = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return (T)Proxy.newProxyInstance(clazz.getClassLoader(),o.getClass().getInterfaces(),this);
}
/**
*
* @param proxy 运行过程中生成的代理对象的实例
* @param method 被代理类的正在被执行的方法
* @param args 该方法对应的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用接口方法
System.out.println((String)args[0]);
method.invoke(o,args);
//方法返回值
return null;
}
}
4.main方法:
public class Main {
public static void main(String[] args){
ProxyInf proxyInf = new ProxyGenerate().newProxyInstance(ProxyImpl.class);
proxyInf.testProxy("哈哈哈");
System.out.println("...");
}
}
PS:最后再总结一下,我在debug的时候发现会出现 Method threw 'java.lang.NullPointerException' exception. Cannot evaluate com.sun.proxy.$Proxy0.toString(),但是不影响程序的正常运行,应该是由于动态代理的时候生成的对象可能并没有toString()方法,而debug模式下是通过toString来打印信息的。所以也解释了为什么在invoke方法中可以返回真实的代理对象