Java代理深入讲解之静态代理

 更新时间:2020年09月08日 09:48:31   作者:Mr.栋  
这篇文章主要给大家介绍了关于Java静态代理的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

什么是代理

代理就是给目标对象一个代理对象,并由代理对象控制目标的引用。

为什么要使用代理模式

1、通过引入代理对象的方式,可以间接的访问目标对象,避免直接访问目标对象给系统带来不必要的复杂性。

2、通过代理对象可以对原有的业务进行业务增强处理。

举例:如果我们需要买国外的某一件商品A,这个时候我们一般有两个途径要么直接去国外买,要么可以找一些代购人员帮我们去购买。在这种情况下,我们由于直接去国外买,实在是太耗软妹币,而且还要花时间等等,这个时候我们最优的选择就是找代购购买,这样也帮我们省去了很多麻烦的事情。

代理模式类图

代码示例

抽象对象:

public interface ITargetFactoryService {

 void sale(String name);
}

目标对象:

@Slf4j
public class TargetFactoryServiceImpl implements ITargetFactoryService {

 @Override
 public void sale(String name) {
  log.info(name+"购买了商品A");
 }
}

代理对象:

@Slf4j
public class ProxyImpl implements ITargetFactoryService {

 public ITargetFactoryService service;

 public ProxyImpl(ITargetFactoryService service){
  super();
  this.service = service;
 }

 @Override
 public void sale(String name) {
  before();
  service.sale("代购");
  after();

 }

 /**
  * 后置增强
  */
 private void after() {
  log.info("代购在购买后得到了市场调研结果");
 }

 /**
  * 前置增强
  */
 private void before() {
  log.info("代购在购买前做了市场调研");
 }
}

测试类:

@Slf4j
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
public class SpsringJdbcApplication {

 public static void main(String[] args) {
  TargetFactoryServiceImpl service = new TargetFactoryServiceImpl();
  ProxyImpl proxy = new ProxyImpl(service);
  proxy.sale("代购");
  SpringApplication.run(SpsringJdbcApplication.class, args);
 }

}

测试结果:

我们可以在代码示例中清晰的看到,在代理类中,代理对象包含了目标对象,并且在业务处理上进行了一定的业务扩展,但是却和目标对象继承于同一个接口。但是此扩展基于Spring AOP来讲,以更加专业的叫法为前置增强、后置增强。

此类代理便是我们常说的静态代理,静态代理适合在业务比较简单,实现类少,需求变化不频繁,但是却要对原有目标服务对象功能进行扩展,并且不去修改原有服务,这个时候我们就可以选择使用静态代理。

静态代理的缺点

如果此时我们业务需要进行扩展,我们的代购同学在经过市场调研以后,发现商品B更加受大家欢迎,这个时候我们就需要对自己的业务进行扩展了,怎么扩展呢?一起接着往下看。

抽象对象:

public interface ITargetFactoryBService {

  void saleB(String name);
}

目标对象:

@Slf4j
public class ITargetFactoryBServiceImpl implements ITargetFactoryBService {

  @Override
  public void saleB(String name) {
    log.info(name + "购买了商品B");
  }
}

代理对象:

@Slf4j
public class ProxyTwoImpl implements ITargetFactoryService, ITargetFactoryBService {

  public ITargetFactoryService service;

  public ITargetFactoryBService bService;

  public ProxyTwoImpl(ITargetFactoryService service,ITargetFactoryBService bService){
    super();
    this.service = service;
    this.bService = bService;
  }

  @Override
  public void sale(String name) {
    before();
    service.sale("代购");
    after();

  }

  @Override
  public void saleB(String name) {
    before();
    bService.saleB("代购");
    after();
  }

  /**
   * 后置增强
   */
  private void after() {
    log.info("代购在购买后得到了市场调研结果");
  }

  /**
   * 前置增强
   */
  private void before() {
    log.info("代购在购买前做了市场调研");
  }


}

测试类:

@Slf4j
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
public class SpsringJdbcApplication {

 public static void main(String[] args) {
  TargetFactoryServiceImpl service = new TargetFactoryServiceImpl();
  ITargetFactoryBServiceImpl bService = new ITargetFactoryBServiceImpl();
  ProxyTwoImpl proxy2 = new ProxyTwoImpl(service, bService);
  proxy2.sale("代购");
  proxy2.saleB("代购");
  SpringApplication.run(SpsringJdbcApplication.class, args);
 }

}

结果:

我们可以看到,在实现业务扩展的时候,需要对原有的代理类进行修改,如果后期我们需要扩展的业务较多的时候,这个类将变的更加繁杂,大量的继承以及方法重写,以至于牵一发而动全身,所以在这种业务扩展性高、业务变化频繁的情况下我们不建议使用静态代理。

静态代理总结:

1、违反Java设计模式开闭原则,即:程序对外扩展开放,对修改关闭。当需求进行变更时,我们应该是新增代码块来实现,而不是在原来的代码中进行修改实现。

2、扩展性很差。

3、可维护性差。

4、代码耦合度高。

总结

到此这篇关于Java代理深入讲解之静态代理的文章就介绍到这了,更多相关Java静态代理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中List数组用逗号分隔开转成字符串2种方法

    java中List数组用逗号分隔开转成字符串2种方法

    在我们日常开发中,在前后端交互的时候会遇到多个id或其他字段存放到一个字段中,这时我们会遇到一个List(集合)---->String(单个字段),这篇文章主要给大家介绍了关于java中List数组用逗号分隔开转成字符串的2种方法,需要的朋友可以参考下
    2023-10-10
  • SpringMVC中的HandlerMapping和HandlerAdapter详解

    SpringMVC中的HandlerMapping和HandlerAdapter详解

    这篇文章主要介绍了SpringMVC中的HandlerMapping和HandlerAdapter详解,在Spring MVC中,HandlerMapping(处理器映射器)用于确定请求处理器对象,请求处理器可以是任何对象,只要它们使用了@Controller注解或注解@RequestMapping,需要的朋友可以参考下
    2023-08-08
  • 关于pom.xml中maven无法下载springcloud包问题

    关于pom.xml中maven无法下载springcloud包问题

    小编遇到这样一个问题spring-cloud-starter-feign,spring-cloud-starter-eureka 一直无法下载,maven仓库中包路径显示为unknown,怎么解决呢?下面小编给大家带来了pom.xml中maven无法下载springcloud包问题,需要的朋友可以参考下
    2022-08-08
  • java web项目Session获取不到问题及解决

    java web项目Session获取不到问题及解决

    这篇文章主要介绍了java web项目Session获取不到问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • spring boot集成rabbitmq的实例教程

    spring boot集成rabbitmq的实例教程

    这篇文章主要给大家介绍了关于spring boot集成rabbitmq的相关资料,springboot集成RabbitMQ非常简单,文中通过示例代码介绍的非常详细,需要的朋友们可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • spring boot如何使用AOP统一处理web请求

    spring boot如何使用AOP统一处理web请求

    这篇文章主要介绍了spring boot如何使用AOP统一处理web请求,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 详解Spring Boot2 Webflux的全局异常处理

    详解Spring Boot2 Webflux的全局异常处理

    这篇文章主要介绍了详解Spring Boot2 Webflux的全局异常处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Java中的Vector和ArrayList区别及比较

    Java中的Vector和ArrayList区别及比较

    这篇文章主要介绍了Java中的Vector和ArrayList区别及比较,本文从API、同步、数据增长、使用模式4个方面总结了它们之间的不同之处,需要的朋友可以参考下
    2015-03-03
  • 如何在JDK 9中更简洁使用 try-with-resources 语句

    如何在JDK 9中更简洁使用 try-with-resources 语句

    本文详细介绍了自 JDK 7 引入的 try-with-resources 语句的原理和用法,以及介绍了 JDK 9 对 try-with-resources 的改进,使得用户可以更加方便、简洁的使用 try-with-resources 语句。,需要的朋友可以参考下
    2019-06-06
  • java数据结构排序算法之树形选择排序详解

    java数据结构排序算法之树形选择排序详解

    这篇文章主要介绍了java数据结构排序算法之树形选择排序,结合具体实例形式分析了java树形选择排序的原理、实现技巧与相关注意事项,需要的朋友可以参考下
    2017-05-05

最新评论