【问题标题】:How to set multiple targets to ProxyFactoryBean and invoke one of the target method based on Config?如何将多个目标设置为 ProxyFactoryBean 并基于 Config 调用目标方法之一?
【发布时间】:2023-04-07 01:50:02
【问题描述】:

在 java 中,我想实现代理类(代理工厂 Bean),它将采用多个目标(实现相同的接口)并调用基于目标方法的配置值之一。

Dog & Cat 实现 Animal 并基于一些配置值(Y 或 N)想要调用它的实现之一。这可以使用策略来完成,但我的问题是类似的逻辑需要应用于其他实现不同接口的实现。(下面的示例我在实现 Car Interface 的 Audi 和 Benz 类下面添加)并希望根据配置选择实现.

  public interface Animal
        {

          public void sound();

        }

        public class Dog implements Animal
        {

          public void sound()
          {

            System.out.print("bark");
          }
        }

        public class Cat implements Animal
        {

          public void sound()
          {

            System.out.print("Meow");
          }
        }

第二个豆子:

public interface Car
  {

    public void make();

  }

  public class Audi implements Car
  {

    public void make()
    {

      System.out.print("Audi");
    }
  }

  public class Benz implements Car
  {

    public void make()
    {

      System.out.print("Mercedes");
    }
  }

示例弹簧配置

<bean id "animalService" class="proxyFactoryBean">
<list>
<target id"Y". "class"="com.Dog">
<target id"N". "class"="com.Cat">
<list>
</bean>

<bean id "carService" class="proxyFactoryBean">
<list>
<target id"Y". "class"="com.Audi">
<target id"N". "class"="com.Benz">
<list>
</bean>

并且在控制器中注入相同的接口(汽车,动物)并在没有任何代理注入的情况下调用原始方法。

有人可以建议如何使用 SpringProxyFactoryBean 或自定义实现来完成吗?

基本上在代理类中,我想检查配置值,并根据我想在该特定实现对象上调用方法。

如果配置值为 Y ,则从定义的目标列表中,获取代理中的 Y bean 引用并在其上调用方法。

【问题讨论】:

    标签: java spring spring-boot spring-mvc java-8


    【解决方案1】:

    代理通常用于在调用目标实现之前拦截对方法调用(最好是接口方法)的请求。

    Spring 在 ProxyFactoryBean 的帮助下允许这样做。您将其配置为代理一个或多个接口(不同类型)、一个目标实现和一个或多个拦截器。当您要求实现这些接口中的任何一个时,配置的拦截器有机会嗅探,但最终调用目标类上的调用方法。

    不太确定您的最终目标是什么,但您所要做的就是创建一个间接并根据某些条件调用 A 类实现或 B 类实现。 ProxyFactoryBean 没有直接解决这个问题。

    其中一个选项是为 ProxyFactoryBean 创建多个 Spring 托管 bean,每个实现一个,并按名称从工厂获取 bean。他们的 id 名称显然会有所不同。

    第二个选项是让您创建第三个实现接口的类,将该类指定为 Spring 配置中的目标,并根据您的条件调用 Class A 实现或 Class B 实现。看一下示例代码 sn-p。

    class CarDecider implements Car{
    /*  
    either get Audi impl from BeanFactory or ApplicationContext 
    if they are configured beans
    or create a new instance in case you don't have access to 
    BeanFactory and serving through singleton instance is not a 
    requirement
    */
        public void make(){
          if(<your condition for Audi true>){  
            beanFactory.getBean(Audi.class).make(); 
            // OR
            new Audi().make();
          }else{
            beanFactory.getBean(Benz.class).make(); 
            // OR
            new Benz().make();
          }
        }
    }
    
    

    第三个选项是你完全避免使用 ProxyFactoryBean。使用不同的名称为接口注册两个实现,并根据 BeanFactory 的条件请求它们。

    【讨论】:

    • 谢谢,如果我选择第二个选项(决策者),我需要为实现不同接口的所有服务编写决策者类,跨应用程序,为每个服务接口(有两个实现)并选择一个其中取决于全局配置。例如-如果品牌是亚马逊,则选择亚马逊实施,或者如果品牌是 shopify,则选择 shopify 实施。这适用于跨应用程序的所有服务。我只想编写一种代理类型的 bean,它将检查全局配置值(Amazon/Shopify)并从列表中配置的两个中选择一个实现。
    • 在这种情况下,您确实需要考虑 ProxyFactoryBean 是否适合您。请参阅答案中提供的第三个选项
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多