静态代理
静态代理就是我们自己写代理类,在代理类中实现代理:
public class StaticProxy implements IRentingHouse{private IRentingHouse rentingHouse;public StaticProxy(IRentingHouse rentingHouse) {this.rentingHouse = rentingHouse;}@Overridepublic void rentingHouse() {rentingHouse.rentingHouse();}}
动态代理
JDK动态代理
public class JdkProxy {private static JdkProxy jdkProxy = new JdkProxy();private JdkProxy() {}public static JdkProxy getInstance() {return jdkProxy;}public Object getProxyByObj(Object obj) {Object result = Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), (proxy, method, args) -> {System.out.println("增强方法前");Object invoke = method.invoke(obj, args);System.out.println("增强方法后");return invoke;});return result;}public <T> T getProxyByClass(Class<T> clazz) {Object result = Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), new Class[]{clazz}, (proxy, method, args) -> {System.out.println("增强方法前");Object invoke = method.invoke(clazz, args);System.out.println("增强方法后");return invoke;});return (T) result;}public static void main(String[] args) {IRentingHouse rentingHouse = new MyRentingHouse();// jdkIRentingHouse proxy = (IRentingHouse) JdkProxy.getInstance().getProxyByObj(rentingHouse);proxy.rentingHouse();}}
CgLib动态代理
public class CgLibProxy {private static CgLibProxy cgLibProxy = new CgLibProxy();private CgLibProxy() {}public static CgLibProxy getInstance() {return cgLibProxy;}public Object getProxyObject(Object obj) {return Enhancer.create(obj.getClass(), (MethodInterceptor) (o1, method, objects, methodProxy) -> {System.out.println("方法增强前");Object invoke = method.invoke(obj, objects);System.out.println("方法增强后");return invoke;});}public static void main(String[] args) {IRentingHouse rentingHouse = new MyRentingHouse();// cglibIRentingHouse proxy = (IRentingHouse) CgLibProxy.getInstance().getProxyObject(rentingHouse);proxy.rentingHouse();}}
总结
静态代理和动态代理的区别
唯一区别就是静态代理需要手写代理类,而动态代理是不需要的,我们虽然在动态代理的时候写了类,但这个类只是为了更好的实现一个代码的解耦,不需要也是可以的。
JDK动态代理与CgLib动态代理
区别在于JDk动态代理必须实现接口,因为在Proxy在生成代理对象的时候我们需要使用接口类;而CgLib动态代理不需要代理类去实现接口,传递当前对象即可。
