动态代理是采用JDK或第三方jar包动态生成代理类的一种代理模式,常用的第三方的有CGLib,动态代理比静态代理使用更方便,使用场景也更多,多用于AOP场景做前置或后置统一控制
JDK自带的代理类,是基于接口来生成的,所以必须传入具体接口才能动态生成代理类,并且还需要传入处理方法InvocationHandler,这样动态生成的代理类才知道怎么处理,动态代理是基于反射实现的,其类都位于反射包下
JDK动态代理处理类需要实现InvocationHandler接口,实现其invoke方法,并且通过构造函数注入需要代理的类,在invoke方法中调用被代理类类的方法,这样就可以在被代理类方法调用之前或之后做一些处理,因为最终JDK基于传入接口动态生成的代理类其都会统一实现调用invoke方法,而在invoke方法内部会调用其持有的真实类的方法,这样就完成了从代理类到真实类的过度,也就可以实现调用过程中的AOP编程
public interface Star { //签合同 void signContract(); //唱歌 void sing(); //收尾款 void collectMoney(); } //========================================= public class RealStar implements Star { @Override public void signContract() { System.out.println("RealStar 签合同"); } @Override public void sing() { System.out.println("RealStar 唱歌"); } @Override public void collectMoney() { System.out.println("RealStar 收尾款"); } } //========================================== import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class StarHandler implements InvocationHandler { private Star star; public StarHandler(Star star) { this.star = star; //通过构造函数注入真是类的引用 } //只要触发代理类方法,那么就会最终触发invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("被代理类类方法调用之前做处理"); method.invoke(star, args);//如果被代理类方法有返回值,这里还可以接收并返回其返回值 System.out.println("被代理类类方法调用之后做处理"); return null; } } //========================================= @Test public void func() { Star realStar=new RealStar(); StarHandler handler=new StarHandler(realStar); //传入接口和处理类,获取代理对象 Star proxy = (Star)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {Star.class}, handler); proxy.sing();//代理对象触发具体方法,最终会触发处理类的invoke方法 }