0
点赞
收藏
分享

微信扫一扫

Java中的静态代理

书呆鱼 2021-10-15 阅读 60
技术分享
什么是静态代理?

代理模式,客户端不会直接去访问真实对象,而是通过代理的方式间接访问真实对象。所谓静态代理,就是在程序运行之前就已经存在代理文件了,是我们自己创建的代理对象,即代理对象和真实对象在程序运行前就确定了。

静态代理实现简单事务管理

在我们的应用中,很多地方都要用到事务,像保存、更新这样的操作,没有事务管理是万万不能的。一般在我们的业务代码中冗杂这事务代码,随着业务的增加,要一直重复着事务代码,业务代码和事务代码耦合,不利于扩展维护。我们先来看一下原先的代码是如何实现的。

public interface EmployeeService {

    void save();

    void update();
}
public class EmployeeServiceImpl implements EmployeeService {

    public void save() {
        System.out.println("调用DAO中的方法执行保存");
    }

    public void update() {
        System.out.println("调用DAO中的方法执行更新");
    }
}
public class TransactionManager {

    public void begin() {
        System.out.println("开启事务");
    }

    public void commit() {
        System.out.println("提交事务");
    }

    public void rollback() {
        System.out.println("回滚事务");
    }
}

在上述代码中,我们模拟员工的service进行保存操作,用TransactionManager模拟事务场景,那么现在我们在测试类中测试员工的保存操作,并加上事务。

@Test
public void test() {
    EmployeeService employee = new EmployeeServiceImpl();
    TransactionManager transactionManager = new TransactionManager();
    try {
        transactionManager.begin();
        employee.save();
        transactionManager.commit();
    } catch (Exception e) {
        e.printStackTrace();
        transactionManager.rollback();
    }
}

运行程序,观察测试结果为

开启事务
调用DAO中的方法执行保存
提交事务

可以看到,我们已经将事务集成到了业务代码中,实现了事务管理。事实上,我们并不希望关于事务的代码和业务代码写到一起,在service中,我们只想专注于业务代码。且尤其对于数据库操作的增删改,对于使用事务来讲,都是大同小异的。所以既然我们不想做跟事务相关的,那么交给谁来做呢?此时就要想到使用一个代理类来帮我们做这样的事。如果是静态代理,代理对象在运行前确定,那么先要创建代理类。所以接下来我们使用静态代理,来代理真实对象的要做的事。

首先要明确一点,我们使用代理类来帮真实对象做一些事,但是核心业务还是真实对象自己做的,所以在代理类中需要持有真实对象的引用,即代理类帮谁做事,就要持有谁的引用。就好比中介给你租房子,那么房子最终是你自己住,海外代购给你买化妆品,真正用化妆品的是你自己。

public class EmployeeProxy implements EmployeeService {

    private EmployeeService employee;

    private TransactionManager transactionManager = new TransactionManager();

    public EmployeeProxy(EmployeeService employee) {
        this.employee = employee;
    }

    public void save() {
        try {
            System.out.println("日志:保存操作...");
            transactionManager.begin();
            employee.save();
            transactionManager.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transactionManager.rollback();
        }
    }

    public void update() {
        try {
            System.out.println("日志:更新操作...");
            transactionManager.begin();
            employee.update();
            transactionManager.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transactionManager.rollback();
        }
    }
}

那么接下来进行测试

@Test
public void testStaticProxy() {
    EmployeeService employee = new EmployeeServiceImpl();
    EmployeeProxy proxy = new EmployeeProxy(employee);
    proxy.save();
}
日志:保存操作...
开启事务
调用DAO中的方法执行保存
提交事务

测试结果和上面是一样的,同样实现了事务管理,而且还增加了日志。代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口。因为代理类是我们自己创建的,在运行之前就存在了,所以叫静态代理。

举报

相关推荐

0 条评论