1、静态代理(Static Proxy)
什么是代理?
举个例子:我开了一家电影公司,我要拍电影赚钱,那么我就要请明星大牌,比如成龙,但是明星都有经纪人,明星只需要演戏即可,而经纪人则帮助明星完成一些比如生活,商业上的沟通,在这里成龙就是真正的类,既被代理类,而经纪人就是代理类,演戏这个动作就是某个业务逻辑方法,经纪人负责联系明星,但是真正演戏的还是成龙
代理分为静态代理和动态代理,静态代理是在编译时就将接口、实现类、代理类一股脑儿全部手动完成
直接实例化对象,然后调用对象的方法就可以完成功能,为什么还要加个代理呢?
原因是:
(1)代理模式能够将正真的对象隔离,降低了系统的耦合度,保证程序的粒度完整
(2)代理类可以在对真正类发出请求之前进行一些额外的操作,例如权限检查等
2、代理实现的一般模式
其实代理的一般模式就是静态代理的实现模式:首先创建一个接口(JDK代理都是面向接口的),然后创建具体实现类来实现这个接口,在创建一个代理类同样实现这个接口,不同之处在于,真正实现类的方法中实现了具体的业务逻辑功能,而代理类中的方法只要调用具体类中的对应方法,这样我们在需要使用接口中的某个方法的功能时直接调用代理类的方法即可,将具体的实现类隐藏在底层
举例:
1.新建一个Iuser接口:
package com.test.proxy;
public interface Iuser {
void eat(String s);
}
2.新建Iuser实现类UserImpl, 为被代理类,既真正的类
package com.test.proxy;
public class UserImpl implements Iuser{
public void eat(String s){
System.out.println("开始吃"+s);
}
}
3.新建UserProxy类,代理类
package com.test.proxy;
public class UserProxy implements Iuser {
private Iuser user = new UserImpl();
@Override
public void eat(String s) {
System.out.println("静态代理前dosomething");
user.eat(s);
System.out.println("静态代理后dosomething");
}
}
4.新建tersor测试类,测试
package com.test.proxy;
import org.junit.Test;
public class Testor {
@Test
public void test() throws Exception {
UserProxy proxy=new UserProxy();
proxy.eat("炸鸡");
}
}
运行结果:
可见,静态代理就是在真正类上包了一层代理类
2、动态代理
好了,一部戏请一个明星肯定不够,我还得请李连杰,周星驰等明星,那么我就得联系多个明星的经纪人,现实中是得这么做,可是在程序中,我想要只联系一个经纪人就能请来多个明星,怎么办呢
这个时候就需要动态代理了:
动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能
1.新建一个Iuser接口:
package com.test.proxy;
public interface Iuser {
void eat(String s);
}
2.新建Iuser实现类UserImpl, 为被代理类,既真正的类
package com.test.proxy;
public class UserImpl implements Iuser{
public void eat(String s){
System.out.println("开始吃"+s);
}
}
3.创建实现InvocationHandler接口的代理类
package com.test.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler{
private Object object;//用于接收真正类的对象
public DynamicProxy(Object obj) {
this.object=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理前dosomething");
method.invoke(this.object, args);
System.out.println("动态代理后dosomething");
return null;
}
}
4.测试类Testor
@Test
public void test1() {
Iuser user = new UserImpl();
InvocationHandler dyProxy = new DynamicProxy(user);
Iuser proxy = (Iuser) Proxy.newProxyInstance(Iuser.class.getClassLoader(), new Class[] { Iuser.class },
dyProxy);
proxy.eat("香肠");
}
运行结果为: