1 代理
我们不直接的去调用一个方法,这样可以不用去改动原来的代码。我理解就是一个AOP概念。
2 静态代理
静态代理很容易理解:我们编写一个代理对象,实现被代理对象相同的接口。在代理对象内部转调被代理对象。
写一个例子:
1.接口和被代理类
// 被代理对象接口
public interface Person
{
void eat();
void study();
}
// 被代理的类
public class Student implements Person
{
private String name = "三和小钢炮";
public void eat()
{
System.out.println(this.name + "eat");
}
public void study()
{
System.out.println(this.name + "study java");
}
}
2.静态代理类
静态代理类也实现Person接口,同时将代理对象传入其内部。
public class PersonProxy implements Person
{
private Person personed;
public PersonProxy(Person person)
{
personed = person;
}
public void eat()
{
System.out.println("eat before");
personed.eat();
}
public void study()
{
System.out.println("study before");
personed.study();
}
}
3.测试类
我们试下:
public class Test
{
public static void main(String[] args)
{
Person person = new Student();
Person proxy = new PersonProxy(person);
proxy.study();
proxy.eat();
}
}
打印结果:
study before
三和小钢炮study java
eat before
三和小钢炮eat
3 动态代理
静态代理,必须一个个方法去适配,这样子不仅辛苦,也没有必要。我们用反射动态解决。
复用上面代码,我们写一个动态代理类:
public class PersonProxyHandler implements InvocationHandler
{
private Object proxyed;
public PersonProxyHandler(Object proxyed)
{
this.proxyed = proxyed;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println(method.getName() + " before");
return method.invoke(proxyed, args);
}
}
测试类:
public class Test
{
public static void main(String[] args)
{
Person person = new Student();
ClassLoader personLoader = Person.class.getClassLoader();
Class<?>[] interfaces = new Class[] { Person.class };
InvocationHandler personProxyHandler = new PersonProxyHandler(person);
Person proxy = (Person) Proxy.newProxyInstance(personLoader, interfaces, personProxyHandler);
proxy.study();
proxy.eat();
}
}
打印结果:
study before
三和小钢炮study java
eat before
三和小钢炮eat
这里运用了newProxyInstance这个类
public static Object newProxyInstance(
ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException
{
}
newProxyInstance,方法有三个参数:
loader: 用哪个类加载器去加载代理对象
interfaces:动态代理类需要实现的接口
h:动态代理方法在执行时,会调用h里面的invoke方法去执行