2012-12-07 21 views
1

使用吉斯,可以做到以下幾點:解決 「機器人腿」 問題與Spring IOC(DI)

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); 
    } 
} 

我如何使用JSR-330(選購)註釋和JavaConfig不使用實現與Spring 3.X(3.1.X或3.2)同樣的事情XML配置?

回答

1

我能找到的是以下(機器人和腿部*類不改變的定義)最近:

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(); 
    } 
} 
+0

這是廢話,春天真的沒有更好的解決方案嗎?來自2006年的這個線程展示了一個有趣的FactoryBean方法http://forum.spring.io/forum/spring-projects/container/13533-exporting-child-applicationcontext-beans-to-the-parent-applicationcontext –

2

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); 
} 
} 
+0

怎麼辦_constructor injection_? ...我糾正了我的問題,並宣佈字段'final',以便更清楚地表明我需要不可變的'Robot'並且我還想使用JSR-330註釋來代替Spring特定的 –

+0

另外一個我不明白的問題是:leftLeg_'如何綁定到'class LeftLeg'和'rightLeg_'''class RightLeg' –

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; 
    } 

    // ... 
} 

reference

0

描述了一個有趣的方法在spring forum。 您需要以某種方式獲得對子環境的引用,我不喜歡那裏提供的方法,但我應該有其他方法。

用法:

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

的FactoryBean代碼:

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()); 
    } 
}