【Spring】代理模式--静态代理

1. 什么是代理模式:

代理:自己不做,找人帮你做。
代理模式:在一个原有功能的基础上添加新的功能。
分类:静态代理和动态代理。

2. 静态代理

2.1 原有方式:核心业务和服务方法都编写在一起

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

2.2 基于类的静态代理

将服务性代码分离出来,核心业务–保存业务中只有保存功能

public class TeamService { 
    public void add(){ 
        System.out.println("TeamService---- add----");
        // 核心业务 
    } 
}

核心业务就是由被代理对象完成 ;其他服务功能由代理类完成

public class ProxyTeamService extends TeamService { 
    public void add(){ 
        try { 
            System.out.println("开始事务"); 
            super.add();
            System.out.println("提交事务"); 
        }catch (Exception e){ 
            System.out.println("回滚事务"); 
        } 
    }
}

弊端:代理类只能代理一个类

2.3 基于接口的静态代理

为核心业务(保存add)创建一个接口,通过接口暴露被代理的方法
要求:代理类和被代理类都实现了同一个接口
接口定义核心方法

public interface IService { 
    void add(); 
}
public class TeamService implements IService{ 
    @Override 
    public void add(){ 
        System.out.println("TeamService---- add----");// 核心业务 
    } 
}
public class UserService implements IService{ 
    @Override 
    public void add() { 
        System.out.println("UserService---- add-----"); // 核心业务
    } 
}

代理类和被代理类实现同一个接口
事务代理类:

public class ProxyTranService implements IService { 
    private IService service;//被代理的对象 
    public ProxyTranService(IService service) { 
        this.service = service; 
    } 
    @Override 
    public void add() { 
        try { 
            System.out.println("开始事务"); 
            service.add();
            //核心业务就是由被代理对象完成 ;其他服务功能由代理类完成 
            System.out.println("提交事务"); 
        }catch (Exception e){ 
            System.out.println("回滚事务"); 
        } 
    }
}

日志代理类:

public class ProxyLogService implements IService { 
    private IService service;//被代理对象 
    public ProxyLogService(IService service) { 
        this.service = service; 
    }
    @Override 
    public void add() { 
        try { 
            System.out.println("开始日志"); 
            service.add();
            //核心业务就是由被代理对象完成 ;其他服务功能由代理类完成 
            System.out.println("结束日志"); 
        }catch (Exception e){ 
            System.out.println("异常日志"); 
        } 
    } 
}

测试类:

public static void main(String[] args) { 
    TeamService teamService=new TeamService();//被代理对象 
    UserService userService=new UserService();//被代理对象 
    ProxyTranService tranService=new ProxyTranService(userService);
    //事务代理 对象--一级代理 
    //tranService.add();//代理对象干活 
    ProxyLogService logService=new ProxyLogService(tranService);
    //日志的代理对 象--二级代理 
    logService.add(); 
}

2.4 提取出切面代码,作为AOP接口(优化)

切面:类似于服务性代码,要切入到核心的代码当中
共有4个位置可以将切面代码编织进入核心业务代码中。
切面接口:

public interface AOP { 
    void before(); 
    void after(); 
    void exception(); 
    void myFinally(); 
}

事务切面类:

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 myFinally() { 
        System.out.println("事务----myFinally"); 
    } 
}

日志切面类:

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 myFinally() { 
        System.out.println("日志----myFinally"); 
    } 
}

代理类:

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 add() { 
        try { 
            aop.before(); 
            service.add();//被代理对象干活 
            aop.after(); 
        }catch (Exception e){ 
            aop.exception(); 
        }finally { 
            aop.myFinally(); 
        }
    }
}

测试类:

@Test 
public void test02(){ 
    IService teamService=new TeamService();//被代理对象--核心内容 
    AOP logAop=new LogAop();//切面-服务内容 
    AOP tranAop=new TranAOP(); 
    //代理对象--一级 代理 
    IService service=new ProxyAOPService(teamService,logAop); 
    //代理对象--二级代理 
    IService service2=new ProxyAOPService(service,tranAop);
    service2.add(); 
}

总结静态代理:

  1. 可以做到在不修改目标对象的功能前提下,对目标对象功能扩展。
  2. 缺点: 因为代理对象,需要与目标对象实现一样的接口。所以会有很多代理类,类太多。
    一旦接口增加方法,目标对象与代理对象都要维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王某人@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值