- 代理模式是一种设计模式,能够使得再不修改源目标的情况下,额外扩展源目标的功能。即通过访问源目标的代理类,再由代理类去访问源目标。这样一来,要扩展功能,就无需修改源目标的代码了。只要在代理上增加就可以了
package StaticProxy;
//里面有wakeup和sleep两个方法
public interface Person {
void wakeup();
void sleep();
}
package StaticProxy;
public interface Animal {
void wakeup();
void sleep();
}
它们有各自的实现类,以student和dog举例
package StaticProxy;
public class Student implements Person{
private String name;
public Student(String name){
this.name = name;
}
@Override
public void wakeup() {
System.out.println("学生" + name + "起床了");
}
@Override
public void sleep() {
System.out.println("学生" + name + "睡觉了");
}
}
package StaticProxy;
public class Dog implements Animal{
private String name;
public Dog(String name){
this.name = name;
}
@Override
public void wakeup() {
System.out.println("dog" + name + "起床了");
}
@Override
public void sleep() {
System.out.println("dog" + name + "睡觉了");
}
}
这时候假设我们现在要在wakeup()前增加一行输出"早安",sleep()前增加一行输出"晚安",通过直接修改实现类肯定是不大好的,这里列举了student和dog,肯定会有很多种类,一个个修改工作量太大了,可以针对两个接口实现两个静态代理类
package StaticProxy;
public class PersonProxy implements Person{
private Person person;
public PersonProxy(Person person){
this.person = person;
}
@Override
public void wakeup() {
System.out.println("早安");
person.wakeup();
}
@Override
public void sleep() {
System.out.println("晚安");
person.sleep();
}
}
package StaticProxy;
public class AnimalProxy implements Animal{
private Animal animal;
public AnimalProxy(Person person){
this.animal = animal;
}
@Override
public void wakeup() {
System.out.println("早安");
animal.wakeup();
}
@Override
public void sleep() {
System.out.println("晚安");
animal.sleep();
}
}
如上所示,在代理类中增加打印"早安"和"晚安",最终执行代码如下
package StaticProxy;
public class MainApp {
public static void main(String[] args) {
Person student = new Student("李世民");
PersonProxy personProxy = new PersonProxy(student);
personProxy.wakeup();
personProxy.sleep();
Person student1 = new Student("朱元璋");
PersonProxy personProxy1 = new PersonProxy(student1);
personProxy.wakeup();
personProxy.sleep();
Animal animal = new Dog("王专家");
AnimalProxy animalProxy = new AnimalProxy(animal);
animalProxy.wakeup();
animalProxy.sleep();
Animal animal1 = new Dog("李专家");
AnimalProxy animalProxy1 = new AnimalProxy(animal1);
animalProxy.wakeup();
animalProxy.sleep();
}
}
这种模式很好理解,这里用了两个代理类,分别代理了Person和Animal接口,但是缺点也很明显:
用JDK动态代理实现上述例子
package RunProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class JdkProxy implements InvocationHandler {
private Object bean;
public JdkProxy(Object bean){
this.bean = bean;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if (methodName.equals("wakeup")){
System.out.println("早安");
}else if (methodName.equals("sleep")){
System.out.println("晚安");
}
return method.invoke(bean,args);
}
}
执行代码
/*
Proxy.newProxyInstance,该方法有三个参数:
loader:用哪个类加载器去加载代理对象
interfaces:动态代理类需要实现的接口
h:InvocationHandler类型:动态代理方法在执行时,会调用h里面的invoke方法去执行
*/
package RunProxy;
import StaticProxy.Animal;
import StaticProxy.Dog;
import StaticProxy.Person;
import StaticProxy.Student;
import java.lang.reflect.Proxy;
public class MainApp {
public static void main(String[] args) {
JdkProxy proxy = new JdkProxy(new Student("李世民"));
Person student = (Person) Proxy.newProxyInstance(
proxy.getClass().getClassLoader(),
new Class[]{Person.class},
proxy);
student.wakeup();
student.sleep();
proxy = new JdkProxy(new Student("朱元璋"));
Person student1 = (Person) Proxy.newProxyInstance(
proxy.getClass().getClassLoader(),
new Class[]{Person.class},
proxy);
student1.wakeup();
student1.sleep();
proxy = new JdkProxy(new Dog("王专家"));
Animal animal = (Animal) Proxy.newProxyInstance(
proxy.getClass().getClassLoader(),
new Class[]{Animal.class},
proxy);
animal.wakeup();
animal.sleep();
proxy = new JdkProxy(new Dog("李专家"));
Animal animal1 = (Animal) Proxy.newProxyInstance(
proxy.getClass().getClassLoader(),
new Class[]{Animal.class},
proxy);
animal1.wakeup();
animal1.sleep();
}
}