【问题标题】:Dependency Injection in Hadoop MapperHadoop Mapper 中的依赖注入
【发布时间】:2014-09-06 12:30:06
【问题描述】:

我想在我的 Mapper 类中注入一个依赖项。

示例映射器类:

public class Mapper() {
    private MyInterface myObject;       

    public void map() {
       // Map code here
    }
}

我想使用 Spring 将 MyInterface 的实现注入到 myObject。 这是不可能直接使用 spring 的,因为 Hadoop 框架本身会实例化 Mapper 对象。

我能做的唯一方法是向我的 Mapper 类添加一个配置函数,然后执行以下操作:

public void configure() {
    // create application context here, then
    myObject= (MyInterface) applicationContext.getBean("bean.myImplementation1");
}

有没有更好的方法来做到这一点?

提前致谢

【问题讨论】:

  • 下面的句子我看不懂我想用Spring给myObject注入一个MyInterface的实现你能解释一下吗?
  • @Skizzo:嗨,假设我有两个 MyInterface 的实现,imp1 和 imp2。我可以选择在运行时将其中 1 个注入到 myObject 变量中。通常可以通过注入 spring bean 来实现。

标签: spring hadoop mapper


【解决方案1】:

这是 Hadoop 上的一个常见困境,因为 Mapper 和 Reducer 是由框架交给你的。我发现最好从 setup() 方法调用轻量级 DI 框架。阅读我关于Dependency Injection on Hadoop 的博文。我编写了一个单独的类来处理名为 Spit-DI 的 DI,它在 github 上可用,并使用 JSR-250 @Resource 注释进行注入。

它最终看起来像这样:

class MovieMapper extends Mapper {
   @Resource
   private Movie movie;

   @Override
   protected void setup(Context context) {
      DependencyInjector.instance().using(context).injectOn(this);
   }
}

class Movie {
   @Resource
   private Counter numMoviesRequested;
   
   public Integer getYear(String title) { 
     numMoviesRequested.increment(1);
     // more code...
   }
}

/**
 * You can have a wrapper class around Spit-DI for all your configuration.
 * (We have a TestDependencyInjector as well for the context of unit testing.)
 */
class DependencyInjector {
   private SpitDI spit = new SpitDI();

   public void injectOn(Object instance) {
      spit.inject(instance);
   }

   public DependencyInjector using(final Mapper.Context context) {
      spit.bindByType(Movie.class, new Movie());
      spit.bindByName(Counter.class, "numMoviesRequested", context.getCounter("movies", "numMoviesRequested");
      return this;
   }
}

【讨论】:

    【解决方案2】:

    阅读了几本关于 Hadoop 的书籍。似乎,'configure()' 方法是唯一的方法。

    已经在问题中添加代码

    【讨论】:

      【解决方案3】:

      spring 中默认的注入方式是基于对象的类型。在您的情况下,您不能使用这种注入,因为您有相同接口的两个不同实现。然后在您的情况下,您可以使用以下策略来注入这些对象(我认为您对 Spring 有一个 xml 配置)

      <beans>
         <context:annotation-config/>
         <bean class="example.MyFirstImpl">
           <qualifier value="first"/>
         </bean>
         <bean class="example.MySecondImpl">
            <qualifier value="second"/>
         </bean>
         <bean class="example.TestComponent" />
      
      
      </beans>
      

      然后在你的界面上就可以使用了

          public class TestComponent {
      
             @Autowired
             @Qualifier("first")
             MyInterface myInterface
      
      }
      

      【讨论】:

      • 我想你回答了一个不同的问题。问题想知道如何注入依赖项(这是不可能的,因为 Hadoop 框架不使用 DI 框架来实例化映射器/缩减器。)将 @Autowired 添加到 Hadoop 映射器不会导致该字段在 Hadoop 时被设置为任何值运行映射器。
      猜你喜欢
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 2014-06-12
      • 2013-04-10
      相关资源
      最近更新 更多