一般而言,動態代理分為兩種,一種是JDK反射機制提供的代理,另一種是CGLIB代理。在JDK代理,必須提供接口,而CGLIB則不需要提供接口,在Mybatis里兩種動態代理技術都已經使用了,在Mybatis中通常在延遲加載的時候才會用到CGLIB動態代理。
1.JDK動態代理:
public interface Rent { public void rent(); }
public class Landlord implements Rent{ @Override public void rent() { System.out.println("房東要出租房子了!"); } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Intermediary implements InvocationHandler{ private Object post; Intermediary(Object post){ this.post = post; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invoke = method.invoke(post, args); System.out.println("中介:該房源已發布!"); return invoke; } }
import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { Rent rent = new Landlord(); Intermediary intermediary = new Intermediary(rent); Rent rentProxy = (Rent) Proxy.newProxyInstance(rent.getClass().getClassLoader(), rent.getClass().getInterfaces(), intermediary); rentProxy.rent(); } }
2.CGLIB動態代理:
public class Landlord { public void rent(){ System.out.println("房東要出租房子了!"); } }
import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class Intermediary implements MethodInterceptor { @Override public Object intercept(Object object, Method method, Object[] args,MethodProxy methodProxy) throws Throwable { Object intercept = methodProxy.invokeSuper(object, args); System.out.println("中介:該房源已發布!"); return intercept; } }
import net.sf.cglib.proxy.Enhancer; public class Test { public static void main(String[] args) { Intermediary intermediary = new Intermediary(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Landlord.class); enhancer.setCallback(intermediary); Landlord rentProxy = (Landlord) enhancer.create(); rentProxy.rent(); } }