假设一个场景,一个客户需要租房,然后找到中介,中介那里有很多房源。房东负责出租,那么中介就带客户去:(1)看房 (2)房东出粗(3) 签合同 (4)收中介费
①创建一个房东接口并创建一个具体的房东实现这个接口
public interface Rent {
void rent(); //出租
}
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东出租房屋");
}
}
②创建一个代理对象(中介) 调用房东租房并附带一些其他的 *** 作
public class Proxy {
private Host host;
public Proxy(Host host) {
this.host = host;
}
public void rent(){
System.out.println("带看房");
host.rent();
System.out.println("签合同");
System.out.println("收房租");
}
}
③测试
public class Client {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host); //中介帮房东租房子 但是呢 中介会进行一些附加的 *** 作
proxy.rent();
}
}
//打印
// 带看房
// 房东出租房屋
// 签合同
// 收房租
说白了就是对某个具体的类中的方法进行了增强。不影响被代理类的 *** 作的同时对代理类的 *** 作进行了增强.
优点:
- 可以时被代理的类的功能更加纯粹,不用去关注一些公共的业务
- 公共业务交给了代理它的类,实现了业务的分工
- 也便于公共业务发生扩展
缺点:
- 一个被被代理的类就得产生一个代理他的类,代码量会增加,开发效率会变低。
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的!
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
基于接口–JDK动态代理
基于类:cglib动态代理
需要了解两个类:
Proxy(代理),提供创建代理类实例的静态方法
InvocationHandler(调用处理程序):每个代理对象都需要一个InvocationHandler去进行关联,代理对象调用方法时会调用InvocationHandler中的invoke方法,然后我们可以在这个方法中对被代理中的方法进行增强。
①创建一个房东接口并创建一个具体的房东实现这个接口
public interface Rent {
void rent();
}
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东出租房屋");
}
}
②创建一个用来生成代理对象的类
//等会儿我们用这个类 ,自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成一个代理类
public Object getProxy(){
return Proxy.newProxyInstance(rent.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
//处理代理实例并返回处理结果 (这个方法是生成的代理类调用方法是自动调用的,相当于这个方法会拦截代理对象调用的方法 然后对该方法进行增强)
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("看房");
Object result = method.invoke(rent, args);//通过反射 执行rent中的方法
//打印被调用的方法的名称
// System.out.println(method.getName());
System.out.println("签合同");
System.out.println("收中介费");
return result;
}
}
③测试
public class Client {
public static void main(String[] args) {
//真实角色(被代理的对象)
Host host = new Host();
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host);//设置要代理的对象
//拿到我们的代理对象
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}
}
//执行结果打印
//看房
//房东出租房屋
//签合同
//收中介费
注意:当然 这个地方可以变得更加万能和灵活,将ProxyInvocationHandler 中的Rent换成Object,这样我们想对哪个类进行代理都行.
动态代理的好处:
- 可以使真实角色的 *** 作更加纯粹!不用去关注一些公共的业务.
- 公共业务就交给代理对象!实现业务的分工!
- 不用像静态代理那样对于每一个需要被代理的类都手写一个代理类。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)