代理模式是一种结构型设计模式,它可以为其他对象提供一种代理以控制对这个对象的访问。
所谓代理,是指具有与被代理对象相同的接口的类,客户端必须通过代理与被代理的目标类进行交互,而代理一般在交互的过程中(交互前后),进行某些特定的处理。
- 我的技术博客:https://nezha.github.io,https://nezhaxiaozi.coding.me
- 我的简书地址:https://www.jianshu.com/u/a5153fbb0434
类视图
-
IUserDao
:是接口类,接口类可以有多个实现类,这样代理类就可以灵活的改变注入的实现类,而不需要修改代理类的代码。 -
UserDao
:是IUserDao
的实现类,这里有具体的实现逻辑。 -
UserDaoProxy
:是代理类,由于需要拦截接口的save()
方法,所以需要也要实现接口IUserDao
;当然代理类也是要实现UserDao
的实现方法的,所以这里需要注入UserDao
的对象到target
。 -
App
:这个是客户端的调用,主要的逻辑是将目标对象UserDao
注入到代理类中去,然后使用代理类来实现save()
方法。
代码实现
1.设计接口
public interface IUserDao {
void save();
}
2.实现接口
public class UserDao implements IUserDao {
@Override
public void save() {
System.out.println("----已经保存数据!----");
}
}
3.代理类
必须实现接口
public class UserDaoProxy implements IUserDao {
//接收保存目标对象
private IUserDao target;
public UserDaoProxy(IUserDao target){
this.target=target;
}
@Override
public void save() {
System.out.println("开始事务...");
target.save();//执行目标对象的方法
System.out.println("提交事务...");
}
}
代理类的核心:
- 需要指明具体的实现类是哪个
-->>
这里通过构造方法传入具体的实现类 `target``; - 需要拦截实现类中的执行方法
-->>
也就是说当客户端执行save()
方法时需要拦截方法,并且可以加入一些额外的操作。
4.测试类
public class App {
public static void main(String[] args) {
//目标对象
UserDao target = new UserDao();
//代理对象,把目标对象传给代理对象,建立代理关系
UserDaoProxy proxy = new UserDaoProxy(target);
proxy.save();//执行的是代理的方法
}
}
客户端需要将具体的接口实现类
UserDao
注入到代理类中去,然后由代理类来执行相应的方法。
应用场景
1.Spring中Bean容器的注入就是结合反射和动态代理实现的
2.Spring中的面向切面编程也使用了动态代理的思想
Spring
的Proxy
模式在AOP
中有体现,比如JdkDynamicAopProxy
和Cglib2AopProxy
。
关于上面两种动态代理的实现可以参考我的文章:Java中的三种代理模式
网友评论