1.定义
代理可以理解为做什么事情在不同的环境之下事先准备工作和工作结束之后需要完成工作都是不一样的。
代理在java中可以分为静态和动态两种方式
2.静态代理
在java世界中代理说白了有两个类都继承一个接口,都要实现接口的方法,但是其中一个类属于另一个类的成员,另外一个类进行接口方法时也需要调用成员继承接口的方法
我们拿学汽车驾驶来举例,最简单的动作就是驾驶,学员也驾驶,教练也要驾驶,但是教练驾驶不是自已,而是教学员,学员在驾驶时他们需要帮他做准备工作,学员驾驶完了需要完成的工作,以下代码是具体的使用静态代理实现:
public interface IDriverService {
void drive();
}
@Data
public class Driver implements IDriverService{
private String name;
@Override
public void drive() {
System.out.println(this.name+"汽车发动,驾驶汽车");
}
}
public class Coach implements IDriverService {
private Driver student;
public void setStudent(Driver student) {
this.student = student;
}
@Override
public void drive() {
before();
student.drive();
end();
}
private void before(){
System.out.println("检查四周环境,告知学员可以开车");
}
private void end(){
System.out.println("到达目的地,停车");
}
}
测试方法:
@Test
public void staticProxy(){
Driver student1=new Driver();
student1.setName("王小人");
Coach coach=new Coach();
coach.setStudent(student1);
coach.drive();
Driver student2=new Driver();
student2.setName("周XXX");
coach.setStudent(student2);
coach.drive();
}
运行日志:
检查四周环境,告知学员可以开车
王小人汽车发动,驾驶汽车
到达目的地,停车
检查四周环境,告知学员可以开车
周XXX汽车发动,驾驶汽车
到达目的地,停车
3.动态代理
从静态代理的例子类中我们可以看出他只适用一类型的学员,如果教练说我除了教人,我还可以教动物园的猴子狮子来学车,用上的方法可能不能实现,但是java中有一种代理机制来实现,下现是准备内容,增加了两个类,一个代理类和动物类
public class Animal implements IDriverService {
private String name;
private String zoomname;
public Animal(String name,String zoomname){
this.name=name;
this.zoomname=zoomname;
}
@Override
public void drive() {
System.out.println("大家小心了,"+this.zoomname+"的"+this.name+"开车了");
}
}
public class CoachDynamicProxy implements InvocationHandler {
private Object target;
public Object setStudent(Object target) {
this.target=target;
Class<?> clazz=target.getClass();
Object o=Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
System.out.println(o.getClass().getName());
return o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object obj=method.invoke(this.target,args);
end();
return obj;
}
private void before(){
System.out.println("检查四周环境,告知学员可以开车");
}
private void end(){
System.out.println("到达目的地,停车");
}
}
测试方法:
@Test
public void DynamicProxy() throws Exception{
Driver student1=new Driver();
student1.setName("王小人");
CoachDynamicProxy coach=new CoachDynamicProxy();
IDriverService o=(IDriverService)coach.setStudent(student1);
o.drive();
Driver student2=new Driver();
student2.setName("周XXX");
o=(IDriverService)coach.setStudent(student2);
o.drive();
o=(IDriverService)coach.setStudent(new Animal("猴子A","苏州动物园"));
o.drive();
o=(IDriverService)coach.setStudent(new Animal("老虎A","上海动物园"));
o.drive();
}
运行日志:
com.sun.proxy.$Proxy9
检查四周环境,告知学员可以开车
王小人汽车发动,驾驶汽车
到达目的地,停车
com.sun.proxy.$Proxy9
检查四周环境,告知学员可以开车
周XXX汽车发动,驾驶汽车
到达目的地,停车
com.sun.proxy.$Proxy9
检查四周环境,告知学员可以开车
大家小心了,苏州动物园的猴子A开车了
到达目的地,停车
com.sun.proxy.$Proxy9
检查四周环境,告知学员可以开车
大家小心了,上海动物园的老虎A开车了
到达目的地,停车
4.扩展
但是以上动态代理只是继承了IDriverSerivce的方式来,但是我们也可以修改,比如让Animal继承其他接口,这样可以增加灵活性
public interface IJumpService {
void jump();
void eat();
}
public class Animal implements IJumpService {
private String name;
private String zoomname;
public Animal(String name,String zoomname){
this.name=name;
this.zoomname=zoomname;
}
@Override
public void jump() {
System.out.println("大家小心了,"+this.zoomname+"的"+this.name+"要做jump动作了");
}
@Override
public void eat() {
System.out.println("大家小心了,"+this.zoomname+"的"+this.name+"要做开始进食了");
}
}
测试方法:
@Test
public void DynamicProxy() throws Exception{
Driver student1=new Driver();
student1.setName("王小人");
CoachDynamicProxy coach=new CoachDynamicProxy();
IDriverService o=(IDriverService)coach.setStudent(student1);
o.drive();
Driver student2=new Driver();
student2.setName("周XXX");
o=(IDriverService)coach.setStudent(student2);
o.drive();
IJumpService o1=(IJumpService)coach.setStudent(new Animal("猴子A","苏州动物园"));
o1.jump();
o1.eat();
o1=(IJumpService)coach.setStudent(new Animal("老虎A","上海动物园"));
o1.jump();
o1.eat();
}
测试日志:
com.sun.proxy.$Proxy9
检查四周环境,告知学员可以开车
大家小心了,苏州动物园的猴子A要做jump动作了
到达目的地,停车
检查四周环境,告知学员可以开车
大家小心了,苏州动物园的猴子A要做开始进食了
到达目的地,停车
com.sun.proxy.$Proxy9
检查四周环境,告知学员可以开车
大家小心了,上海动物园的老虎A要做jump动作了
到达目的地,停车
检查四周环境,告知学员可以开车
大家小心了,上海动物园的老虎A要做开始进食了
到达目的地,停车