代理模式提供了对对象的另外一种访问方式,即通过代理对象访问目标对象。当不能或不想直接访问目标对象时,就可以使用代理模式。代理模式实现的关键是代理对象与目标对象。代理对象是对目标对象的扩展,并且会调用目标对象。
1.静态代理
静态代理需要目标对象和代理对象实现相同的接口或者相同的父类
示例:
//目标接口
package proxy;
public interface IAnimalDao {
public void run();
}
//目标类
package proxy;
public class DogDao implements IAnimalDao{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("dog run......");
}
}
//代理类
package proxy;
public class ProxyDao implements IAnimalDao{
private IAnimalDao target;
public ProxyDao(IAnimalDao target) {
this.target=target;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("开始事务");
//
target.run();
System.out.println("提交事务");
}
}
//测试类
package proxy;
public class StaticProxyDemo {
public static void main(String args[]) {
DogDao dogDao=new DogDao();
IAnimalDao proxy=new ProxyDao(dogDao);
proxy.run();
}
}
输出:
开始事务
dog run......
提交事务
总结:静态代理需要代理对象也实现和目标对象相同的接口,当目标对象修改时,需要同时维护代理对象
2.动态代理
动态代理不需要实现和目标对象一样的接口。jdk中提供了api用于构建代理对象
示例:
//目标接口
package proxy;
public interface IAnimalDao {
public void run();
}
//目标对象
package proxy;
public class DogDao implements IAnimalDao{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("dog run......");
}
}
//产生代理类实例
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DogProxy {
private Object target;
public DogProxy(Object target) {
this.target=target;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("开始事务");
Object value=method.invoke(target, args);
System.out.println("提交事务");
return value;
}
});
}
}
//测试类
package proxy;
public class DynamicProxyDemo {
public static void main(String args[]) {
IAnimalDao target=new DogDao();
IAnimalDao proxy=(IAnimalDao) new DogProxy(target).getProxyInstance();
proxy.run();
}
}
输出:
开始事务
dog run......
提交事务
总结:代理对象不需要实现接口,但目标对象一定要实现接口,不然不能使用jdk动态代理