1

使用 Guice,可以执行以下操作:

interface Leg {}

_

class LeftLeg implements Leg {
    public String toString() {
        return "LeftLeg";
    }
}

_

class RightLeg implements Leg {
    public String toString() {
        return "RightLeg";
    }
}

_

class Robot {
    final Leg leftLeg_;
    final Leg rightLeg_;

    @Inject
    Robot(@Named("left") Leg leftLeg, @Named("right") Leg rightLeg) {
        leftLeg_ = leftLeg;
        rightLeg_ = rightLeg;
    }

    public String toString() {
        return "leftLeg_=" + leftLeg_ + ", rightLeg_=" + rightLeg_;
    }
}

_

class RobotTest {
    @Test
    public void t1() throws Exception {
        Injector inj = Guice.createInjector(new AnGuiceModule());
        Robot r = inj.getInstance(Robot.class);
        assertEquals(r.toString(), "leftLeg_=LeftLeg, rightLeg_=RightLeg");
    }
}

_

class AnGuiceModule extends AbstractModule {
    protected void configure() {
        bind(Leg.class).annotatedWith(Names.named("left")).to(LeftLeg.class);
        bind(Leg.class).annotatedWith(Names.named("right")).to(RightLeg.class);
    }
}

在不使用 XML 配置的情况下,如何使用 JSR-330(可选)注释和 JavaConfig 使用 Spring 3.x(3.1.x 或 3.2)实现相同的目标?

4

4 回答 4

1

interface Leg {}

_

 @Component
 class LeftLeg implements Leg {
  public String toString() {
    return "LeftLeg";
  }
 }

_

@Component
class RightLeg implements Leg {
  public String toString() {
    return "RightLeg";
 }
}

_

class Robot {
  @Autowired
  Leg leftLeg_;
  @Autowired
  Leg rightLeg_;



  public String toString() {
    return "leftLeg_=" + leftLeg_ + ", rightLeg_=" + rightLeg_;
 }
}

_

@RunWith(SpringJUnit4ClassRunner.class)
class RobotTest {
  @Autowired
  Robot r;
  @Test
  public void t1() throws Exception {
     System.out.println(r);
 }
}
于 2012-12-07T04:52:00.110 回答
1

你可以这样做;虽然这个使用了 Spring 注释、@Qualifier 和 @Autowired,但我看不出它不能与 @Named 和 @Inject 一起使用的任何理由,你应该尝试:

public class MovieRecommender {

  private MovieCatalog movieCatalog;
  private CustomerPreferenceDao customerPreferenceDao;

  @Autowired
  public void prepare(@Qualifier("main") MovieCatalog movieCatalog,
                      CustomerPreferenceDao customerPreferenceDao) {
      this.movieCatalog = movieCatalog;
      this.customerPreferenceDao = customerPreferenceDao;
  }

  // ...
}

示例取自参考资料

于 2012-12-07T08:09:12.423 回答
1

我能找到的最接近的是(Robot 和 Leg* 类的定义没有改变):

public class RobotTest {

    @Test
    public void t1() throws Exception {
        ApplicationContext ctx = new 
               AnnotationConfigApplicationContext(RobotConfig.class, Robot.class);
        Robot r = ctx.getBean(Robot.class);
        assertEquals("leftLeg_=LeftLeg, rightLeg_=RightLeg", r.toString());
    }
}

@Configuration
class RobotConfig {

    @Bean
    public Leg leftLeg() {
        return new LeftLeg();
    }

    @Bean
    public Leg rightLeg() {
        return new RightLeg();
    }

}

替代方案是:

public class RobotTest {

    @Test public void t1() throws Exception {
        ApplicationContext ctx = new 
               AnnotationConfigApplicationContext(RobotConfig.class);
        Robot r = ctx.getBean(Robot.class);
        assertEquals("leftLeg_=LeftLeg, rightLeg_=RightLeg", r.toString());
    }
}

@Configuration
class RobotConfig {

   @Bean @Scope("prototype") public Robot robot() {
       return new Robot(leftLeg(), rightLeg());
   }

    @Bean @Scope("prototype") public Leg leftLeg() {
        return new LeftLeg();
    }

    @Bean @Scope("prototype") public Leg rightLeg() {
        return new RightLeg();
    }
}
于 2012-12-09T03:16:24.213 回答
0

spring 论坛上描述了一种有趣的方法。您需要以某种方式获取对子上下文的引用,我不喜欢那里提出的方法,但我应该有其他方法。

用法:

  <bean name="someBean" class="playground.spring.BeanImportFactoryBean">
        <property name="applicationContext" ref="privateCtx"/>
        <property name="importBeanName" value="importBean"/>
    </bean>

工厂豆代码:

public class BeanImportFactoryBean implements FactoryBean, BeanNameAware {
    transient private final Log log = LogFactory.getLog(this.getClass());

    private String beanName;
    private ApplicationContext applicationContext;
    private String importBeanName;

    public BeanImportFactoryBean() {
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void setImportBeanName(String importBeanName) {
        this.importBeanName = importBeanName;
    }

    protected String getUsedBeanName() {
        String returnName;
        if (importBeanName == null) {
            returnName = beanName;
        } else {
            returnName = importBeanName;
        }
        return returnName;
    }

    public Object getObject() throws Exception {
        return this.applicationContext.getBean(getUsedBeanName());
    }

    public Class getObjectType() {
        return this.applicationContext.getType(getUsedBeanName());
    }

    public boolean isSingleton() {
        return this.applicationContext.isSingleton(getUsedBeanName());
    }
}
于 2015-12-04T14:57:03.243 回答