InvocationHandler 接口位于 java.lang.reflect 反射包,搭配使用可以实现比较丰富的动态功能增减。
直接上代码:
一:必须有准备实现动态代理的Interface功能接口
/**
* 准备实现动态代理的接口
*
* @author gbx
*/
public interface RunMethodInterface {
void runA();
void runB();
}
二:接口的实现类
/**
* 接口的实现类
*
* @author gbx
*/
public class RunMethod implements RunMethodInterface {
@Override
public void runA() {
System.out.println("RunMethod runA...");
}
@Override
public void runB() {
System.out.println("RunMethod runB...");
}
}
三:InvocationHandler 接口的自定义实现,主要在这里实现自定义的功能
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
/**
* 动态代理测试
*
* @author gbx
*/
public class GbxInvocationHandler implements InvocationHandler {
/**
* 构造方法引入转化的对象
*/
private Object object;
/**
* InvocationHandler的实现类需要提供一个构造器,用来接收目标对象
* 否则接口中的method是无法执行的,因为没有对象就没有办法执行对象的方法
*
* @param object 要实现代理的对象
*/
public GbxInvocationHandler(Object object) {
this.object = object;
}
/**
* Processes a method invocation on a proxy instance and returns
* the result. This method will be invoked on an invocation handler
* when a method is invoked on a proxy instance that it is
* associated with.
*
* @param proxy the proxy instance that the method was invoked on
* @param method the {@code Method} instance corresponding to
* the interface method invoked on the proxy instance. The declaring
* class of the {@code Method} object will be the interface that
* the method was declared in, which may be a superinterface of the
* proxy interface that the proxy class inherits the method through.
* @param args an array of objects containing the values of the
* arguments passed in the method invocation on the proxy instance,
* or {@code null} if interface method takes no arguments.
* Arguments of primitive types are wrapped in instances of the
* appropriate primitive wrapper class, such as
* {@code java.lang.Integer} or {@code java.lang.Boolean}.
* @return the value to return from the method invocation on the
* proxy instance. If the declared return type of the interface
* method is a primitive type, then the value returned by
* this method must be an instance of the corresponding primitive
* wrapper class; otherwise, it must be a type assignable to the
* declared return type. If the value returned by this method is
* {@code null} and the interface method's return type is
* primitive, then a {@code NullPointerException} will be
* thrown by the method invocation on the proxy instance. If the
* value returned by this method is otherwise not compatible with
* the interface method's declared return type as described above,
* a {@code ClassCastException} will be thrown by the method
* invocation on the proxy instance.
* @throws Throwable the exception to throw from the method
* invocation on the proxy instance. The exception's type must be
* assignable either to any of the exception types declared in the
* {@code throws} clause of the interface method or to the
* unchecked exception types {@code java.lang.RuntimeException}
* or {@code java.lang.Error}. If a checked exception is
* thrown by this method that is not assignable to any of the
* exception types declared in the {@code throws} clause of
* the interface method, then an
* {@link UndeclaredThrowableException
* } containing the
* exception that was thrown by this method will be thrown by the
* method invocation on the proxy instance.
* @see UndeclaredThrowableException
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = null;
try {
//执行目标方法前执行的任意逻辑
System.out.println("GbxInvocationHandler 方法前执行的自定义逻辑...");
//实现代理的对象方法执行
invoke = method.invoke(object, args);
//执行目标方法后执行的任意逻辑
System.out.println("GbxInvocationHandler 方法后执行的自定义逻辑...");
} catch (Exception e) {
System.out.println("GbxInvocationHandler 方法执行异常:" + e.getMessage());
e.printStackTrace();
}
return invoke;
}
}
四:调用方式
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* 测试动态代理
*
* @author gbx
*/
public class TestA {
public static void main(String[] args) {
RunMethodInterface runMethod = new RunMethod();
runMethod.runA();
runMethod.runB();
System.out.println("============================分割线============================");
//开始构建自定义代理
InvocationHandler gbxInvocationHandler = new GbxInvocationHandler(runMethod);
//成功创建目标对象的代理
RunMethodInterface proxyRunMethod = (RunMethodInterface) Proxy.newProxyInstance(gbxInvocationHandler.getClass().getClassLoader(), runMethod.getClass().getInterfaces(), gbxInvocationHandler);
//用代理对象调用相关方法,则执行目标方法和自定义代理中的相关逻辑
proxyRunMethod.runA();
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
proxyRunMethod.runB();
}
}
五:查看程序执行结果
RunMethod runA...
RunMethod runB...
============================分割线============================
GbxInvocationHandler 方法前执行的自定义逻辑...
RunMethod runA...
GbxInvocationHandler 方法后执行的自定义逻辑...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GbxInvocationHandler 方法前执行的自定义逻辑...
RunMethod runB...
GbxInvocationHandler 方法后执行的自定义逻辑...
Over!
发布前,看到扯淡的官方提示,说质量低,不会获得推荐。好吧,能看到此博文的皆是有缘之人!