之前星球的球友面试,问了我一些问题,说让我写一下这个代理,和代理到底是根据什么来进行区分,又该在什么地方使用。这篇文章我细致的讲解一下关于代理的一些问题。
代理分类
-
静态代理
-
动态搭理
静态代理
我们先说静态代理的实现方式,为什么不推荐使用静态代理?
1.继承方式实现代理(静态代理中的继承代理)
1 |
|
静态代理可以看出来一点问题吧?
每次代理都要实现一个类,导致项目中代码很多;你每次想要代理,都要去实现一个类,代码就会成堆的增加,然后你就会发现项目的类就会越来越多,就会导致你们的项目显得很臃肿。而且代码的复用性太低了,并且耦合度非常高,这个我们所说的高内聚低耦合是相悖的。
动态代理
我们在看一下这个动态代理:
1 |
|
上面代码解析
一个 Italk
接口,有空的方法 talk()
(说话),所有的 people
对象都实现(implements)这个接口,实现 talk()
方法,前端有很多地方都将 people
实例化,执行 talk
方法,后来发现这些前端里有一些除了要说话以外还要唱歌(sing),那么我们既不能在 Italk
接口里增加 sing()
方法,又不能在每个前端都增加 sing
方法,我们只有增加一个代理类 talkProxy
,这个代理类里实现 talk
和 sing
方法,然后在需要 sing
方法的客户端调用代理类即可,
这也是实现动态代理的方式,是通过实现(implements)的方式来实现的,这种方法的优点,在编码时,代理逻辑与业务逻辑互相独立,各不影响,没有侵入,没有耦合。
cgLib代理
还有一种是cgLib的代理,这种代理则是适合那些没有接口抽象的类代理,而Java 动态代理适合于那些有接口抽象的类代理。
我们来通过代码了解一下他到底是怎么玩的。
1 |
|
运行结果
1 |
|
实现CGLIB动态代理必须实现MethodInterceptor(方法拦截器)接口,
这个接口只有一个intercept()方法,这个方法有4个参数:
-
obj表示增强的对象,即实现这个接口类的一个对象;
-
method表示要被拦截的方法;
-
args表示要被拦截方法的参数;
-
proxy表示要触发父类的方法对象;
代理的使用
那么什么时候使用静态态代理,什么时候使用动态代理和cgLib代理呢?
一般情况静态代理是很少是用的,因为他对代码的复用性或者说是耦合度都非常不友好,不推荐使用。
如果目标对象至少实现了一个接口,那么就用JDK动态代理,所有由目标对象实现的接口将全部都被代理。
如果目标对象没有实现任何接口,就是个类,那么就用CGLIB代理。
我是懿,一个正在被打击还在努力前进的码农。欢迎大家关注我们的公众号,加入我们的知识星球,我们在知识星球中等着你的加入。