`
lixinpingfriendhu
  • 浏览: 437 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

解决构选不确定问题,使用spring3注解

    博客分类:
  • java
阅读更多

更多文章

package com.mcnz.spring;

public class GameSummary {

 

  private String clientChoice, serverChoice, result;

 private java.util.Date date = null;

 

  String[] choices = {"rock", "paper", "scissors"};

 String[] results = {"win", "lose", "tie"};

 

  public GameSummary(){}

 

  public String getClientChoice() { return clientChoice; }

 public void setClientChoice(String clientChoice) {

   this.clientChoice = clientChoice; 

 }

 public String getServerChoice() { return serverChoice; } 

 public void setServerChoice(String serverChoice) {

   this.serverChoice = serverChoice;

 

  }

 public String getResult() { return result; }

 

  public void setResult(String result) {

   this.result = result;

 } 

 public java.util.Date getDate() { return date; }

 public void setDate(java.util.Date date) {

   this.date = date;

 }

 public String toString() {

   return clientChoice +                                    

     ":" + serverChoice +

       ":" + result + ":" + date;

 }

}

切分这个类的实例不使用Spring XML,我们所需要做的就是写一个小的配置文件,再洒上一些@ bean注释@ configuration,在正确的地方。我们还决定,我们希望GameSummary bean,它表示结果的石头,剪刀和步这个游戏的游戏,是初始化属性,表明客户端已经赢了玩”,所以我们写我们的小配置类像这

package com.mcnz.spring;

import org.springframework.context.annotation.*;

@Configuration

public class SummaryConfig { 

 @Bean

 public GameSummary clientWinsWithPaper() {

   GameSummary gs = new GameSummary();

 

    gs.setClientChoice("paper");

    gs.setServerChoice("rock");

    gs.setResult("win");

 

    return gs;

 }

}

对我来说,我喜欢这样。我觉得它看起来不错。我可以看到一个GameSummay实例被创建在clientWinsWithPaper()方法,我可以看到属性得到初始化。任何理智的Java程序员会对此表示感谢。疯狂的程序员采取一种不同的方法,使用Spring配置文件,和污染他们的应用程序和XML。这里是你如何会达到相同的结果使用Spring配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 <bean id="clientWinsWithPaper" class="com.mcnz.spring.GameSummary" >

   <property name="clientChoice" value="paper"/>
   <property name="serverChoice" value="rock"/>
   <property name="result" value="win"/>

   </bean>
</beans>

如果您的环境设置正确,你可以运行这两个例子,即弹簧使用XML,春天,在相同的XML没有独立的应用程序。它看起来像这样:

 

package com.mcnz.spring;

 

 import org.springframework.beans.factory.BeanFactory;

 

 import org.springframework.beans.factory.xml.XmlBeanFactory;

 

 import org.springframework.context.annotation.AnnotationConfigApplicationContext;

 

 import org.springframework.core.io.*;

 

 public class SumRunner {

 

 public static void main(String args[]){

 

 /* Spring IoC Without XML */

 

 AnnotationConfigApplicationContext context

 

 = new AnnotationConfigApplicationContext(SummaryConfig.class);

 

 GameSummary gsA

 

 = context.getBean("clientWinsWithPaper", GameSummary.class);

 

 /* Spring IoC with XML */

 

 Resource resource = new ClassPathResource("summary.xml");

 

 BeanFactory beanFactory = new XmlBeanFactory(resource);

 

 GameSummary gsX

 

 = (GameSummary)beanFactory.getBean("clientWinsWithPaper");

 

 System.out.println(gsA);

 

 System.out.println(gsX);

 

 }

 

 }

 

老实说,这个例子并没有真正证明压倒性的分歧使用注释的好处在XMLSpring应用程序。可能是个更好的例子来看看使用一个构造函数来设置初始属性的一个给定的对象,而不是简单地配置bean属性通过setter。比如说,如果我们想要初始化clientChoiceserverChoice属性的GameBean一旦被创建,我们应该做所有这些通过一个缺点

 public GameSummary(String c, String s){

 

 clientChoice = c;

 

 serverChoice = s;

 

 /* result = ???; */

 

 }

 

使用此构造函数来初始化clientChoiceserverChoice属性通过使用@ configuration bean是一个铅管紧握。你只是调用构造器在您的Java代码。下面是它的外表,与先前的调用setter方法所有注释掉:

package com.mcnz.spring;

 

 import org.springframework.context.annotation.*;

 

 @Configuration

 

 public class SummaryConfig {

 

 @Bean

 

 public GameSummary clientWinsWithPaper() {

 

 GameSummary gs = new GameSummary("rock", "paper");

 

 //gs.setClientChoice("paper");

 

 //gs.setServerChoice("rock");

 

 //gs.setResult("win");

 

 return gs ;

 

 }

 

 }

使等效构造函数调用使用XML,您需要使用元素,并通过在constructor - arg你初始化数据通过value属性。你实际上并不需要指定参数类型,春天会去找到一个最佳匹配的构造函数,参数提供。这是它的样子:

 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="clientWinsWithPaper" class="com.mcnz.spring.GameSummary" >
<constructor-arg value="rock"/>
<constructor-arg value="paper"/>
</bean>
</beans>

虽然配置细节在Spring容器已经改变,客户端代码引用不会,所以你可以继续并重新运行SumRunner类。这一次,输出将反映事实和serverGesture clientGesture都被初始化为非空值。

rock:paper:null:null

paper:rock:null:null



现在,为了讨论各种情形,让我们假设我们添加了一个构造函数,初始化了clientGesture和结果属性。这个serverGesture地产仍将是null。我们不能有两个构造函数具有相同参数的签名,所以不要传递一个字符串和一个字符串,我们将使用索引的选择和结果数组,一直挂在未使用的GameSummary:

String[] choices = { "rock", "paper", "scissors" };
String[] results = { "win", "lose", "tie" };

,来初始化clientGesture和结果属性使用一个构造函数,利用适当的指数这两个数组,以下构造函数需要被添加到GameSummary:

 

public GameSummary(int c, int r) {
 clientChoice = choices[c];
 result = results[c];
}


与构造函数代码,我将添加一个新的方法@ configuration,给出一种GameSummary实例,表明客户端获得对选择摇滚。真的,代码为这个新clientWinsWithRock方法不能更简单


@Bean
public GameSummary clientWinsWithRock() {
GameSummary gs = new GameSummary(0, 1);
return gs ;
}


然而,事情变得更复杂的XML文件。如果有人仅仅添加以下进入他们的Spring配置文件,您最终将得到一些非常有bug的代码:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="clientWinsWithPaper" class="com.mcnz.spring.GameSummary" >
<constructor-arg value="rock"/>
<constructor-arg value="paper"/>
</bean>
<bean id="clientWinsWithRock" class="com.mcnz.spring.GameSummary" >
<constructor-arg value="0"/>
<constructor-arg value="1"/>
</bean>
</beans>


如果你调整你的SumRunnerclientWithRock实例的两个注释和XML配置Spring容器,然后跑你的代码,你可能会得到以下错误的结果:


rock:null:win:null
0:1:null:null


现在,有一个简单的解决这个问题。所有您需要做的就是进入你的XML文件并添加类型属性的constructor - arg元素。当然,这是简单的如果你完全理解问题,是一个专家在春天,总是知道去哪里在XML配置文件,它推动超过一千豆条目。注意,这不是一个错误,要么在编译时间或在运行时。这只是一个普通的旧bug,它不是一个缺陷在春天。这是一个错误


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="clientWinsWithPaper" class="com.mcnz.spring.GameSummary" >
<constructor-arg type="java.lang.String" value="rock"/>
<constructor-arg type="java.lang.String" value="paper"/>
</bean>
<bean id="clientWinsWithRock" class="com.mcnz.spring.GameSummary" >
<constructor-arg type="int" value="0" />
<constructor-arg type="int" value="1"/>
</bean>
</beans>

请注意,我们现在有类型属性对于clientWinsWithRockclientWinsWithPaper豆子。当我们运行SumRunner,我们现在得到预期,bug的结果:


rock:null:win:null
rock:null:win:null


现在,有一件事来强调这是是多么简单写一些Java代码调用适当的构造函数,而不是bug拉登路径使用XML。当然,我们的错误是由于缺乏了解的问题域,都是如何工作的,所以我们真的春天都怨不得别人,只能怪自己。当然,我们解决了这个问题,但仍然,想象这是一个大项目。要多长时间重新编译您的工作区,重新运行您的测试套件,文档bug,然后res


 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics