学习动态代理之前,要先掌握静态代理,可以参考参考我之前的文章:
springboot AOP 静态代理
步入正题,什么是JDK动态代理?JDK动态代理是基于接口的代理,JDK动态代理的本质是两级代理,即代理类代理了InvocationHandler,而InvocationHandler又代理了实例类,只要给InvocationHandler声明了实例类所实现的接口,InvocationHandler就可自动实现,不用我们再手动添加。
JDK动态代理Fighter类:
package com.imooc.pattern;
public interface Fighter {
public void kick();
public void fist();
}
它的实现类:
package com.imooc.pattern;
public class RealFighter implements Fighter{
@Override
public void kick(){
System.out.println("ride kick!");
}
@Override
public void fist(){
System.out.println("ride fist!");
}
}
要使我们的Fighter在出拳和出脚的时候都要有准备和结束的动作,我们使用JDK动态代理来实现:
JDK动态代理要实现IncovationHandler这个接口:
package com.imooc.dynamic;
import com.imooc.pattern.Fighter;
import com.imooc.pattern.RealFighter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxyFighter implements InvocationHandler {
//注入实体类
private RealFighter realFighter;
//构造函数
public JDKProxyFighter(RealFighter realFighter){
this.realFighter=realFighter;
}
/*
* 实现InvocationHandler接口必须实现这个方法
* proxy:代理类代理的真实代理对象com.sun.proxy.$Proxy0
* method:我们所要调用某个对象真实的方法的Method对象
* args:指代代理对象方法传递的参数
*/
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("准备");
Object result = null;
result = method.invoke(realFighter,objects);
System.out.println("结束");
//若该方法有返回值则将返回值封装成Object对象返回,若没有返回null
return result;
}
/*
loader:一个classloader对象,定义了由哪个classloader对象对生成的代理类进行加载
interfaces:一个interface对象数组,表示我们将要给我们的代理对象提供一组什么样的接口,如果我们提供了这样一个接口对象数组,那么也就是声明了代理类实现了这些接口,代理类就可以调用接口中声明的所有方法。
h:一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
*/
//创造一个追加功能后的代理类,Fighter类型
public Fighter creat(){
return (Fighter) Proxy.newProxyInstance(JDKProxyFighter.class.getClassLoader(),new Class[]{Fighter.class},new JDKProxyFighter(new RealFighter()));
}
}
好了,JDK动态代理类设置完成,接下来看看怎么用吧:
public static void main(String[] args){
JDKProxyFighter Proxy=new JDKProxyFighter(new RealFighter());
Fighter fighter=Proxy.creat();
fighter.fist();
fighter.kick();
}
结果:
准备
ride fist!
结束
准备
ride kick!
结束
JDK动态代理总结:
定义的JDK代理类要实现InvocationHandler接口,代理类代理InvocationHandler,而InvocationHandler又代理我们的实体类形成两级代理,共同协作完成功能。
JDK动态代理是基于接口的代理,若我们代理的对象并没有实现任何接口的话,那我们需要另外一种动态代理的方法了–CGLIB动态代理。
若有不足,请及时指出。