目录
1:代理是什么鬼
2:代理分类
3:为什么要用代理
4:我们怎么如何代理接口和子类
1->环境(自己去建一个maven项目)
2->静态代理
a:新建个被代理接口类
b:新建个被代理类
c:新建代理类
d:启动运行类
3->动态代理(接口的动态代理)
a:新建个被代理接口类
b:新建个被代理类
c:新建代理类
d:启动运行类
4->动态代理(类的动态代理)
a:pom.xml导入cglib库
b:新建个接口,用来处理代理方法,也方便lamd表示
c:新建个被代理类
d:新建个代理工厂
5:敲黑板
6:下一篇spring-web搭建
7:本章资源下载链接
先说说这篇文章看完你能学习到什么吧
1:代理是什么鬼,2:代理分类,3:为什么要使用代理,4:我们怎么如何代理接口和子类。5:敲黑板
代理就是代为处理方法,增强类的功能,本质就是对类的方法增强(advice),简单来说就是中间商。比如你是厂家,你不想自己卖东西,那么这时候你可以招收代理帮你卖,他可以适当提高价格,卖点中间价,这就是代理。
按生成代理的方式来分,是分为传统的静态代理和动态代理
a:静态代理:传统的代理方式,编译期间已经确定了代理类的代码,简单来说,项目代码中就已经有被代理类(非接口类)和代理类的代码了。
b:动态代理:代理类,编译期间还没生成,而是通过Java虚拟机来去动态的生成代理类,需要的时候动态创建。动态代理又有两种方式-------接口的动态代理,类的动态代理。
回答这个问题前,先问你是否有用过用过Spring-validation这个框架,这个就是用spring-aop进行参数检验,而spring-aop本质就是cglib的动态代理的方式。所以你知道为什么要用代理了,就是能就匹配的方式进行处理增强。从而增强代码模块,也可以实现代码的解耦和美观。
这个部分,我们分为静态代理和动态代理的来讲解。
【jdk8】,【maven3.5】,【intellj idea2018】
public interface Subject { public void resolve(); }
public class BeStaticProxyObject implements Subject{ public void resolve() { System.out.println("我是被“静态代理”的方法,我在终于开始执行了"); } }
public class StaticProxy implements Subject{ private BeStaticProxyObject beStaticProxyObject; public StaticProxy(BeStaticProxyObject beStaticProxyObject) { this.beStaticProxyObject = beStaticProxyObject; } public void resolve() { System.out.println("我是“静态代理”的方法,我在“被代理的方法”之前执行"); beStaticProxyObject.resolve(); } }
public class MainClass { public static void main(String args[]){ BeStaticProxyObject beStaticProxyObject = new BeStaticProxyObject(); StaticProxy staticProxy = new StaticProxy(beStaticProxyObject); staticProxy.resolve(); } }
public interface Subject { public void resolve(); }
public class BeStaticProxyObject implements Subject{ public void resolve() { System.out.println("我是被“静态代理”的方法,我在终于开始执行了"); } }
public class ProxyInteface implements InvocationHandler { BeStaticProxyObject beStaticProxyObject; public ProxyInteface(BeStaticProxyObject beStaticProxyObject) { this.beStaticProxyObject = beStaticProxyObject; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是“动态代理接口”的方法,你想执行被代理的方法,必须经过我拦截和处理"); return method.invoke(this.beStaticProxyObject, args); } }
public class MainClass { public static void main(String args[]){ BeStaticProxyObject beStaticProxyObject = new BeStaticProxyObject(); StaticProxy staticProxy = new StaticProxy(beStaticProxyObject); staticProxy.resolve(); ProxyInteface proxyInteface = new ProxyInteface(beStaticProxyObject); Subject subject = (Subject)Proxy.newProxyInstance(beStaticProxyObject.getClass().getClassLoader(), beStaticProxyObject.getClass().getInterfaces(), proxyInteface); subject.resolve(); }
cglib cglib 3.3.0
public interface ProxyMethodInterceptor { public Object intercept(Object obj, Method method, Object[] args) throws Throwable; }
public class BeStaticProxyObject{ public void resolve() { System.out.println("我是被“代理”的方法,我在终于开始执行了"); } }
public class ProxyFactory implements MethodInterceptor { private Object target; private ProxyMethodInterceptor interceptor; private ProxyFactory(Object target, ProxyMethodInterceptor interceptor) { this.target = target; this.interceptor = interceptor; } @SuppressWarnings("unchecked") public staticT getProxyInstance(Object target, ProxyMethodInterceptor interceptor) { ProxyFactory pf = new ProxyFactory(target, interceptor); Enhancer en = new Enhancer(); en.setSuperclass(target.getClass()); en.setCallback(pf); return (T)en.create(); } public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { return interceptor.intercept(target, method, args); } }
e:启动运行类
public class MainClass { public static void main(String args[]){ BeStaticProxyObject beStaticProxyObject = new BeStaticProxyObject(); StaticProxy staticProxy = new StaticProxy(beStaticProxyObject); staticProxy.resolve(); ProxyInteface proxyInteface = new ProxyInteface(beStaticProxyObject); Subject subject = (Subject)Proxy.newProxyInstance(beStaticProxyObject.getClass().getClassLoader(), beStaticProxyObject.getClass().getInterfaces(), proxyInteface); subject.resolve(); BeStaticProxyObject proxyInstance = ProxyFactory.getProxyInstance(beStaticProxyObject, (Object obj, Method method, Object[] nowArgs) -> { System.out.println("我是“动态代理cglib”的方法,你想执行被代理的方法,必须经过我拦截和处理"); return method.invoke(obj, nowArgs); }); proxyInstance.resolve(); } }
1:动态代理接口是通过什么原理实现代理的?
答:动态代理接口是用jdk本身的Proxy类去实现创建个代理对象,这种方式可以返回接口。我们通过接口调用方法,就可以完美实现接口的代理
2:动态代理类是通过什么原理实现代理的?
答:动态代理类是通过cglib库的Enhancer 底层的字节码技术ASM进行类的代理生成,并返回该类。通过类的调用方法,就可以对方法进行拦截和处理。
3:动态代理类的cglib目前有哪些地方有用?
答:我们熟悉的Hibernate就是采用这个。
https://download.csdn.net/download/weixin_36667844/88785686