静态代理
公共的接口(出租房子)
public interface Rent {
void rent();
}
真实的对象(被代理的对象 比如房东)
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要出租房子!");
}
}
代理对象(比如中介)
public class ProxyRent {
private Host host;
public void setHost(Host host) {
this.host = host;
}
public void invoke(){
// 这里先看房子再租房子
this.seeHouse();
host.rent();
}
// 实际业务中可能要增加一些其他业务,但是又要不改变被代理类中的业务
// 比如我现在要增加一个中介带看房的业务
private void seeHouse(){
System.out.println("中介带看房子!");
}
}
最后就是真实的租房者
public class Client {
public static void main(String[] args) {
ProxyRent proxyRent = new ProxyRent();
Host host = new Host();
proxyRent.setHost(host);
proxyRent.invoke();
}
}
这里就是在没有改变原代码的前提下,新增了一个带看房子的业务。
静态代理有比较大的局限性,一个代理类只能代理一个被代理的类,那么当被代理类比较多的时候,那么就需要些很多重复的代码了,在简单的场景中使用比较合适,复杂的场景就可以使用下面的动态代理方式了。
动态代理有两种使用比较广泛的方式实现,他们的底层原理其实差不多,一种是JDK原生的方式,另一种就是CGLib,下面的实例采用JDK的方式实现。
先写出两个接口,以便等会儿做演示
public interface Rent {
void rent();
}
public interface UserService {
void add();
void delete();
void update();
void query();
}
然后时它们的实现类,也就是需要被代理的类
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东要出租房子!");
}
}
public class User implements UserService{
@Override
public void add() {
System.out.println("新增一个用户!");
}
@Override
public void delete() {
System.out.println("删除一个用户!");
}
@Override
public void update() {
System.out.println("修改一个用户!");
}
@Override
public void query() {
System.out.println("查询一个用户!");
}
}
然后就是比较关键的一个类了,我们需要实现InvocationHandler接口
public class ProxyInvocationHandler implements InvocationHandler {
// 这里采用Object类型,就可以代理不同的类了。
private Object target;
public void setTarget(Object target) {
this.target = target;
}
// 生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.log(method.getName());
Object result = method.invoke(target, args);
return result;
}
// 新增其他业务
public void log(String type){
System.out.println(type + "操作。");
}
}
最后测试一下
public class Client {
public static void main(String[] args) {
// 代理User对象
// User user = new User();
//
// ProxyInvocationHandler handler = new ProxyInvocationHandler();
//
// handler.setTarget(user);
// UserService proxy = (UserService) handler.getProxy();
//
// proxy.delete();
// 代理Host对象
Host host = new Host();
ProxyInvocationHandler handler = new ProxyInvocationHandler();
handler.setTarget(host);
Rent proxy = (Rent) handler.getProxy();
proxy.rent();
}
}