静态代理在使用时,需要定义接口
或者父类
,目标对象与代理对象一起实现相同的接口
或者是继承相同父类
。
代理对象通过调用代理对象的方法来调用目标对象的方法;可以在不修改目标对象的前提下,对目标对象的功能进行扩展。
静态代理
静态代理原理
在代理类里,定义一个目标对象(被代理对象)的属性;在调用代理对象时,将目标对象做为代理对象构造方法里的参数传入,代理对象重写目标对象的方法,在重写的方法里包装被代理对象的方法。
这样就可以在代理对象的方法里调用目标对象的方法,可以在代理方法里做一些扩展。在调用时,只需通过代理对象调用自身的方法即可。
构成元素:
- 接口 或 父类
- 接口的实现类 或 继承父类的子类
- 实现同样接口的代理类 或 同样继承父类的代理类
静态代理缺点
一个明显的缺点要为每一个接口类生成一个代理类,也就是一个接口类必然要对应一个代理类。这样必然会生成很多的代理类,并且这些代理类的代码有很多重复的部分。
解决这一问题,最好的办法就是通过一个代理类 完成全部的代理功能,此时就要使用动态代理。
实现接口方式
结构图
接口:
1 2 3 4 5 6
|
public interface UserDao { void save(); }
|
目标对象类(接口实现类):
1 2 3 4 5 6 7 8 9 10
|
public class UserDaoImpl implements UserDao {
@Override public void save() { System.out.println("正在保存"); } }
|
代理对象类(与目标对象实现同一个接口):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
public class UserDaoProxyImpl implements UserDao {
private UserDaoImpl userDaoImpl;
public UserDaoProxyImpl(UserDaoImpl userDaoImpl) { this.userDaoImpl = userDaoImpl; }
@Override public void save() { System.out.println("代理增强: 开始保存。。。。"); userDaoImpl.save(); System.out.println("代理增强: 保存结束。。。。"); }
}
|
客户端调用代理类:
1 2 3 4 5 6 7 8 9
| public class Client {
public static void main(String[] args) { UserDao userDao = new UserDaoImpl(); userDao = new UserDaoProxyImpl(userDao); userDao.save(); } }
|
执行结果:
1 2 3
| 代理增强: 开始保存。。。。 正在保存 代理增强: 保存结束。。。。
|
继承父类方式
父类
1 2 3 4 5 6
| public class BaseMapper {
public void save() { System.out.println("正在保存。。。。"); } }
|
目标对象类(被代理对象类继承父类)
1 2 3 4 5 6 7 8 9 10
|
public class BatchMapper extends BaseMapper {
public void batchSave() { System.out.println("批量保存。。。。"); }
}
|
代理对象类(继承相同的父类)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public class MapperProxy extends BaseMapper {
private BatchMapper batchMapper;
public MapperProxy(BatchMapper batchMapper) { this.batchMapper = batchMapper; }
public void save() { System.out.println("代理增强: 开始保存。。。。"); batchMapper.save(); System.out.println("代理增强: 保存结束。。。。"); }
public void batchSave() { System.out.println("代理增强: 批量保存。。。。"); batchMapper.batchSave(); System.out.println("代理增强: 保存结束。。。。"); } }
|
客户端调用
1 2 3 4 5 6 7 8 9
| public class Client { public static void main(String[] args) { BatchMapper batchMapper = new BatchMapper(); MapperProxy mapperProxy = new MapperProxy(batchMapper); mapperProxy.save(); System.out.println("------------------------------------"); mapperProxy.batchSave(); } }
|
- 执行结果
1 2 3 4 5 6 7
| 代理增强: 开始保存。。。。 正在保存。。。。 代理增强: 保存结束。。。。 ------------------------------------ 代理增强: 批量保存。。。。 批量保存。。。。 代理增强: 保存结束。。。。
|