hadoopMap器中的spring依赖注入

fdbelqdn  于 2021-06-03  发布在  Hadoop
关注(0)|答案(3)|浏览(310)

我想在Map器类中注入一个依赖项。
Map器类示例:

public class Mapper() {
    private MyInterface myObject;       

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

我想使用spring将myinterface的实现注入myobject。直接使用spring是不可能的,因为hadoop框架本身示例化了mapper对象。
唯一的方法是将configure函数添加到mapper类中,然后执行以下操作:

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

有没有更好的办法?
提前谢谢

ht4b089n

ht4b089n1#

看了几本关于hadoop的书。似乎,“configure()”方法是唯一的方法。
已经在问题中添加了代码

ecbunoof

ecbunoof2#

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

<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

}
9lowa7mx

9lowa7mx3#

这在hadoop上是一个常见的难题,因为mapper和reducer是由框架交给您的。我发现最好从setup()方法调用一个轻量级di框架。阅读我关于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;
   }
}

相关问题