代理
代理:我们应该不陌生,最常见的就是我们身边的一些朋友,在朋友圈里边卖东西的人,她们从厂家拿货,然后在朋友圈里边卖给熟人
按道理来说,客户可以直接去找厂家来买,但是呢,现实生活中很少能看到这样的场景,一般都是厂家把货物给代理商,代理商再把货物卖给客户
所以代理商就有点中介的意味
静态代理
静态代理:是在不改变原有代码的基础上,增强功能
代理(Proxy)和厂家(manufactor)都实现资源接口(Resourcesable)中的方法(method())代理的method方法是调用厂家的method方法,此时客户(Client)只需要实现代理中的method方法就是实现了厂家的method方法。
下边看一个具体的例子(租房子)
1、资源接口
package com.zkw.Demon01;
public interface Rent {
public void rentHouse();
}
2、真是角色
package com.zkw.Demon01;
//房东要出租房子
public class Landlord implements Rent {
public void rentHouse() {
System.out.println("房东:我要出租房子");
}
}
3、代理角色
package com.zkw.Demon01;
//中介,房东把房子放到中介所
public class Intermediate implements Rent {
private Landlord landlord;
public Intermediate() {
}
public Intermediate(Landlord landlord) {
this.landlord = landlord;
}
//在Spring中一般使用Set方法来注入 而不是通过有参构造
/* public void setLandlord(Landlord landlord) {
this.landlord = landlord;
}*/
public void seeHouse(){
System.out.println("中介:带领租客去看房");
}
public void rentHouse(){
landlord.rentHouse();
}
public void contract(){
System.out.println("中介:代替房东和租客签租赁合同");
}
public void charge(){
System.out.println("中介;收取费用");
}
}
4、用户
package com.zkw.Demon01;
//租客要租房子
public class Tenant {
public static void main(String[] args) {
//房东
Landlord landlord = new Landlord();
//中介:找到房东,拿到房源,并带领租客去看房
//构造器注入
Intermediate intermediate = new Intermediate(landlord);
//Spring中通过set方法注入
// intermediate.setLandlord(landlord);
//房东的业务
intermediate.rentHouse();
//中介附加的业务
intermediate.seeHouse();
intermediate.contract();
intermediate.charge();
}
}
用户需要租房子,而房东需要出租房子,房东把房子给中介让中介帮忙出租,此时中介就相当于是房东,而用户找到中介让中介帮忙找房子,他要租房子,此时中介带领用户去看房子,如果用户要租就签房屋租赁合同。
结果如图
代理模式的优缺点:
- 优点
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
- 公公也就是交给代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
- 缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率低
动态代理
动态代理主要是运用了反射的机制来实现的
通过使用Proxy提供的方法来生成代理类,通过查看jdk1.8-api它提供了两种方法来创建代理类
解释三个东西:
- ClassLoader:类的加载器
- interfaces:代理类实现接口
- h:调度方法给处理函数
下边看一个具体的例子:
package com.zkw.Demon03;
public interface UserService {
public void add();
public void del();
public void modify();
public void query();
}
package com.zkw.Demon03;
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("增加了一个用户");
}
public void del() {
System.out.println("删除了一个用户");
}
public void modify() {
System.out.println("修改了一个用户");
}
public void query() {
System.out.println("查询了一个用户");
}
}
package com.zkw.Demon03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class PoxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成代理类 this 是因为我们当前类实现了InvocationHandler中的调度方法invoke
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println(method);
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String msg){
System.out.println("使用来"+msg+"方法");
}
}
package com.zkw.Demon03;
public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
PoxyInvocationHandler pih = new PoxyInvocationHandler();
pih.setTarget(userService);
UserService proxy = (UserService) pih.getProxy();
proxy.add();
proxy.del();
proxy.modify();
proxy.query();
}
}
或者把 PoxyInvocationHandler
这个类换成Invocation
package com.zkw.Demon03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Invocation implements InvocationHandler {
private Object target;
public Invocation(Object target) {
this.target = target;
}
/**
* proxy:代表动态代理对象
* method:代表正在执行的方法
* args:代表调用目标方法时传入的实参
*/
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println(method);
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String msg){
System.out.println("使用来"+msg+"方法");
}
}
package com.zkw.Demon03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
InvocationHandler invocation = new Invocation(userService);
//创建一个代理的对象
UserService userProxy1 = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(),
new Class<?>[]{UserService.class}, invocation);
/* UserService userProxy1 = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), invocation);*/
//执行方法
userProxy1.add();
userProxy1.del();
userProxy1.modify();
userProxy1.query();
}
}
结果如下: