一、定义:
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
二、简介:
1.意图:
为其他对象提供一种代理以控制对这个对象的访问。
2.主要解决:
在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
三、这里介绍两种代理模式,静态代理和动态代理
1.静态代理:
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.
java代码:
接口:public interface UserService {
void save();
}
目标实现类:public class UserServiceImpl implements UserService {
public void save() {
System.out.println("-----------save user");
}
}
代理对象:public class UserProxy implements UserService {
private UserService userService;
public UserProxy(UserService userService) {
this.userService=userService;
}
public void save() {
System.out.println("-----------开始事务");
userService.save();
System.out.println("-----------提交事务");
}
}
测试:public static void main(String[] args) {
UserService userService=new UserProxy(new UserServiceImpl());
userService.save();
}
结果:-------开始事务
-----------save user
--------提交事务
2.动态代理:
因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.如何解决静态代理中的缺点呢?答案是可以使用动态代理方式。
动态代理有以下特点:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
java代码:接口和目标类和静态代理一样,代理类是通过一个工厂来得到
代理类工厂类:public class ProxyFactory {
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
//生成代理对象
public Object getProxyInstance(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-------开始事务");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("--------提交事务");
return returnValue;
}
});
}
}
测试:public static void main(String[] args) {
ProxyFactory proxyFactory=new ProxyFactory(new UserServiceImpl());
//创建代理对象
UserService userServiceProxy =(UserService) proxyFactory.getProxyInstance();
userServiceProxy.save();
}
结果:-------开始事务
-----------save user
--------提交事务