代理模式
什么是代理模式?
代理模式就是找一个中介帮你办一些事。你只需要关注自己的事就行了,其他的中介会帮你办好。
代理模式中有三个要素:
- 抽象对象:接口
- 代理对象:类
- 真实对象:类
静态代理
静态代理:有你自己来创建代理对象,每个真实对象都需要由你来创建代理对象。
缺点:如果有很多个真实对象需要被代理,那你需要写很多的代理类。
静态代理的主要思路就是:在代理类中放一个被代理类的对象,通过代理类去实现被代理类的方法。而在被代理方法执行之前或之后,你可以进行一些额外的操作。
代码实现:
interface Eat{
void eat();
}
//真实类
class Person implements Eat{
private String name;
Person(String name){
this.name = name;
}
public String getName(){
return this.name;
}
@Override
public void eat() {
System.out.println(this.name+"吃饭");
}
}
//代理类
class ProxyPerson implements Eat{
private Person person;
ProxyPerson(Person person){
this.person = person;
}
@Override
public void eat() {
System.out.println("帮"+person.getName()+"做饭");
person.eat();
System.out.println("帮"+person.getName()+"洗碗");
}
}
public class StaticProxyTest {
public static void main(String[] args) {
ProxyPerson pp = new ProxyPerson(new Person("小明"));
pp.eat();
}
}
运行结果:
这就是一个静态代理的例子。
动态代理
在静态代理中,代理类是固定的,而动态代理就是可以让代理类动态的生成。这里使用的反射机制。
动态代理通过一个Proxy类和InvocationHandler接口来动态的创建代理类。
代码实现:
interface Eat{
void eat();
}
//真实类
class Person implements Eat{
private String name;
Person(String name){
this.name = name;
}
public String getName(){
return this.name;
}
@Override
public void eat() {
System.out.println(this.name+"吃饭");
}
}
class MyInvocationHandler implements InvocationHandler{
private Object obj;
MyInvocationHandler(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("做饭");
method.invoke(obj);
System.out.println("洗碗");
return null;
}
}
public class StaticProxyTest {
public static void main(String[] args) {
Eat person = new Person("tom");//真实对象
InvocationHandler handler = new MyInvocationHandler(person);
Eat eat = (Eat) Proxy.newProxyInstance(Person.class.getClassLoader(),Person.class.getInterfaces(),handler);
eat.eat();
}
}
运行结果:
动态代理实现步骤
Proxy.newProxyInstance(Person.class.getClassLoader(),Person.class.getInterfaces(),handler);
这句话主要是用来创建一个代理类的对象。
在newProxyInstance这个方法中,先使用反射创建了一个代理类,代理类实现了Person所实现的接口。在代理类中还有一个带有InvocationHandler为参数的构造器,在调用代理对象的方法时,实际上调用的是InvocationHandler中的invoke方法。
总结
今天只是大概的了解一下静态代理和动态代理,对他们的底层实现还需要慢慢了解。