Java静态代理的实现

问题

原有的编写方式,是核心业务与服务性代码一起编写。但像处理事务、记录日志等这些服务性代码基本都一样,且与核心业务关联不大。所以,按照这种从头写到尾的方式编写代码,效率不高。

优化方法

按照代理模式编写代码,意思就是将核心业务和其他业务分离。编写核心业务的类就专心编写核心业务,其他业务就交给代理类编写。

你将收获

看完静态代理,能让你更好的理解动态代理;
明白一种将 核心业务 和 其他业务 分离的方法。

静态代理

1.基于类实现静态代理

首先,编写核心业务(被代理类)类

public class FoodService{

    public void insert(){
        //核心业务
        System.out.println("FoodService----insert");
    }
}

然后,编写代理类(代理类需要继承被代理类)

public class ProxyFoodService extends FoodService {

    public void insert(){
        try {
            System.out.println("开始事务");
            super.insert(); //核心业务
            System.out.println("提交事务");
        } catch (Exception e) {
            System.out.println("回滚事务");
        }
    }
}

看上面核心业务是继承父类的,由FoodService提供;其他 非核心的业务则在代理类中编写。
最后,测试一下
在这里插入图片描述
缺点: 一个核心业务类至少要有一个代理类来对其进行补充,这样要建很多代理类,效率低。

2.基于接口实现静态代理

首先,编写一个接口(与它相关的核心业务类都要实现本接口)

public interface IService {

    void insert();
}

然后,编写一个核心业务类,并实现接口

public class FoodService implements IService{

    @Override
    public void insert(){
        //核心业务
        System.out.println("FoodService----insert");
    }
}

然后,编写一个代理类

  • 私有一个接口对象IService,这个是我们后面要被代理的对象;
  • 写一个一参构造方法,当外面要创建本ProxyTranService 代理对象时,需要传递一个实现了IService接口的核心业务类才能创建代理对象;
  • 本ProxyTranService 代理对象也要实现IService接口;
  • 本类重写的核心方法由外部传进来的被代理对象提供,其他业务由本代理提供。
public class ProxyTranService implements IService {

    private IService service; //被代理对象

    public ProxyTranService(IService service) {
        this.service = service;
    }

    @Override
    public void insert() {
        try {
            System.out.println("开始事务");
            service.insert();  //核心业务是由被代理对象FoodService做,其他由代理类完成
            System.out.println("提交事务");
        } catch (Exception e) {
            System.out.println("回滚事务");
        }
    }
}

最后,测试一下

  • 这里的CustomerService也是一个实现了IService接口的核心业务类;
  • ProxyTranService 是一个代理事务的代理类;
  • ProxyLogService是一个代理日志记录的代理类 。

在这里插入图片描述
优点: 可以实现多个核心业务类重复使用一个代理类;
缺点: 代理类需要实际编写代理业务代码,后面如果要改,会很不方便。

3.实现AOP静态代理

简单介绍:AOP是面向切面编程,我们的非核心业务可以划分为不同的切面。比如记录日志,事务管理都可以划分为一个切面。每一个切面负责好自己该负责的业务就好,能降低代码的关联,提高可复用性。
下面我们要干的事:对 基于接口实现静态代理 进行改进,以实现AOP静态代理

首先,创建一个AOP接口

  • 根据相对于核心业务代码的位置,我们可以将服务型代码划大致分为before、after、exception、finally四种
public interface AOP {

    //这些服务代码,可以基于核心代码的位置来分类
    void before();
    void after();
    void exception();
    void aopFinally();
}

然后,按照需求实现AOP接口

这是一个记录日志的切面

public class LogAOP implements AOP{
    @Override
    public void before() {
        System.out.println("开始日志----before");
    }

    @Override
    public void after() {
        System.out.println("结束日志----after");
    }

    @Override
    public void exception() {
        System.out.println("异常日志----exception");
    }

    @Override
    public void aopFinally() {
        System.out.println("最终日志----finally");
    }
}

这是一个处理事务问题的切面

public class TranAOP implements AOP{

    @Override
    public void before() {
        System.out.println("开始事务----before");
    }

    @Override
    public void after() {
        System.out.println("结束事务----after");
    }

    @Override
    public void exception() {
        System.out.println("事  务----exception");
    }

    @Override
    public void aopFinally() {
        System.out.println("事  务----finally");
    }
}

然后,重写代理类(这时候我们只用编写一个代理类即可完善核心业务)

public class ProxyAOPService implements IService {

    private IService service; //被代理对象
    private AOP aop; //切面

    public ProxyAOPService(IService service, AOP aop) {
        this.service = service;
        this.aop = aop;
    }

    @Override
    public void insert() {
        try {
            aop.before();
            //被代理对象干活
            service.insert();  
            aop.after();
        }catch (Exception e){
            aop.exception();
        }finally {
            aop.aopFinally();
        }
    }
}

最后,测试一下
在这里插入图片描述


谢谢观看,希望看完本文对你有帮助!
end~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值