• Java - 静态代理


    代理的名词

    代理对象:增强后的对象
    目标对象:被增强的对象

    Java代理-静态代理

    静态代理包含继承和聚合两种。

    1. 继承

    代理对象继承目标对象,重写需要增强的方法。

    1. public interface UserDao {
    2. void query();
    3. }
    1. import org.springframework.stereotype.Service;
    2. @Service
    3. public class UserDaoImpl implements UserDao {
    4. @Override
    5. public void query() {
    6. System.out.println("query db");
    7. }
    8. }
    1. public class UserDaoLogImpl extends UserDaoImpl {
    2. @Override
    3. public void query() {
    4. System.out.println("start to query");
    5. super.query();
    6. System.out.println("end to query");
    7. }
    8. }
    1. public class TestApp {
    2. public static void main(String[] args) {
    3. UserDaoImpl dao2 = new UserDaoLogImpl();
    4. dao2.query();
    5. }
    6. }

    `UserDaoLogImpl`是代理对象,`UserDaoImpl`是目标对象。
    代理对象与目标对象时相对的,会根据情况发生变化。`UserDaoLogImpl`以后也会成为目标对象。

    2. 聚合

    1. import com.merckgroup.msizing.domain.service.UserDao;
    2. public class UserDaoOperateImpl implements UserDao {
    3. UserDao userDao;
    4. public UserDaoOperateImpl(UserDao userDao) { // 装饰者模式
    5. this.userDao = userDao;
    6. }
    7. @Override
    8. public void query() {
    9. System.out.println("operate - start to query");
    10. userDao.query();
    11. System.out.println("operate - end to query");
    12. }
    13. }
    1. public class TestApp {
    2. public static void main(String[] args) {
    3. UserDao targetUserDao = new UserDaoImpl();
    4. UserDaoOperateImpl userDaoOperate = new UserDaoOperateImpl(targetUserDao);
    5. userDaoOperate.query();
    6. }
    7. }

    运行结果:

    1. operate - start to query
    2. query db
    3. operate - end to query

    添加时间代理

    1. public class UserDaoTimeImpl implements UserDao {
    2. UserDao userDao;
    3. public UserDaoTimeImpl(UserDao userDao) { // 装饰者模式
    4. this.userDao = userDao;
    5. }
    6. @Override
    7. public void query() {
    8. System.out.println("time - start to query");
    9. userDao.query();
    10. System.out.println("time - end to query");
    11. }
    12. }

    案例

    代理1:对日志代理。A
    代理2:对操作代理。B
    代理3:对时间代理。C

    需求:实现对时间和操作的代理。
    需求-方案1:采用链式继承,继承B时添加时间代理,继承C时添加操作代理。(继承)
    需求-方案2:采用聚合方式

    方案1:比较容易实现

    方案2:实例代码

    1. public class UserDaoTimeImpl implements UserDao {
    2. UserDao userDao;
    3. public UserDaoTimeImpl(UserDao userDao) { // 装饰者模式
    4. this.userDao = userDao;
    5. }
    6. @Override
    7. public void query() {
    8. System.out.println("time - start to query");
    9. userDao.query();
    10. System.out.println("time - end to query");
    11. }
    12. }
    1. public class UserDaoOperateImpl implements UserDao {
    2. UserDao userDao;
    3. public UserDaoOperateImpl(UserDao userDao) { // 装饰者模式
    4. this.userDao = userDao;
    5. }
    6. @Override
    7. public void query() {
    8. System.out.println("operate - start to query");
    9. userDao.query();
    10. System.out.println("operate - end to query");
    11. }
    12. }
    1. public class TestApp {
    2. public static void main(String[] args) {
    3. UserDao target = new UserDaoTimeImpl(new UserDaoImpl()); // 对时间
    4. UserDao userDaoLog = new UserDaoOperateImpl(target); // 继而对操作
    5. userDaoLog.query();
    6. }
    7. }

    运行结果:

    1. operate - start to query
    2. time - start to query
    3. query db
    4. time - end to query
    5. operate - end to query

    结论:使用静态代理时会产生类,继而可能引发类爆炸(继承与聚合皆是如此)。因此,在不确定时尽量减少使用静态代理。

    不确定情况:不明确后续的扩展情况,是否需要扩展接口或者扩展接口的程度如何。

  • 相关阅读:
    运行vue,浏览器出错
    linux内网服务器设置全局代理和yum代理
    【Java面试】TCP协议为什么要设计三次握手?
    iOS自定义滚动条
    有关包装类的一道经典面试题
    399. 除法求值
    Activiti,Apache camel,Netflex conductor对比,业务选型
    机器学习笔记之最优化理论与方法(五)凸优化问题(上)
    Hibernate-Validator 接口参数校验 | 嵌套参数校验
    Flink 本地任务添加配置参数
  • 原文地址:https://blog.csdn.net/A_bad_horse/article/details/126917240