jdk动态代理的实现原理
先写一个jdk动态代理的例子
1.先定义一个接口
public interface MyService {
void print();
}
2.定义一个实现类
public class MyServiceImpl implements MyService{
@Override
public void print() {
System.out.println("原始方法");
}
}
3.实现InvocationHandler接口,实现增强逻辑
public class JdkInvocation implements InvocationHandler {
private Object object;
public JdkInvocation(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("处理前");
Object value = method.invoke(object, args);
System.out.println("处理后");
return value;
}
}
4.测试
public class TestProxy {
public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
MyService myService = new MyServiceImpl();
MyService proxy = (MyService) Proxy.newProxyInstance(myService.getClass().getClassLoader(), new Class[] {MyService.class}
, new JdkInvocation(myService));
proxy.print();
}
}
5.查看生成的代理类
public final class $Proxy0 extends Proxy implements MyService {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void print() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("com.example.demo.proxy.MyService").getMethod("print");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
从生成的代理类的实现可以看到,代理类继承了Proxy类,并实现了我们定义的接口,其中通过构造方法将我们实现InvocationHandler接口的增强类注入进去。
1.因为java是单继承的,所以jdk动态代理只能适用于实现了接口的类。
2.spring中是如何实现通知的
public class JdkInvocation implements InvocationHandler {
private Object object;
public JdkInvocation(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object value = null;
//beforeAdvise(前置通知)
try {
//aroundAdvise(环绕通知)
value = method.invoke(object, args);
//aroundAdvise(环绕通知)
System.out.println("处理后");
}catch (Throwable t) {
//afterThrowingAdvise(异常通知)
}finally {
//afterReturningAdvise(返回值通知)
}
return value;
}
}
还没有评论,来说两句吧...