??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲日本一线产区和二线产区对比,亚洲成年人在线观看,亚洲国产综合精品中文字幕 http://m.tkk7.com/ashutc/category/42982.html沈阳求职Qjava3q以上经验)Qashutc@126.comzh-cnFri, 15 Apr 2011 09:12:43 GMTFri, 15 Apr 2011 09:12:43 GMT60spring3.0注解http://m.tkk7.com/ashutc/archive/2011/04/14/348270.html西瓜西瓜Thu, 14 Apr 2011 02:01:00 GMThttp://m.tkk7.com/ashutc/archive/2011/04/14/348270.htmlhttp://m.tkk7.com/ashutc/comments/348270.htmlhttp://m.tkk7.com/ashutc/archive/2011/04/14/348270.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/348270.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/348270.html使用 @Repository、@Service、@Controller ?@Component 类标识?Bean

Spring ?2.0 版本开始,陆箋引入了一些注解用于简?Spring 的开发。@Repository 注解便属于最先引入的一批,它用于将数据讉K?(DAO ?) 的类标识?Spring Bean。具体只需该注解标注?DAO cM卛_。同ӞZ?Spring 能够扫描c\径中的类q识别出 @Repository 注解Q需要在 XML 配置文g中启?Bean 的自动扫描功能,q可以通过 <context:component-scan/> 实现。如下所C:(x)

 // 首先使用 @Repository ?DAO cd明ؓ(f) Bean
 package bookstore.dao;
 @Repository
 public class UserDaoImpl implements UserDao{ …… }

 // 其次Q在 XML 配置文g中启?Spring 的自动扫描功?br />  <beans … >
    ……
 <context:component-scan base-package=”bookstore.dao” />
……
 </beans>
 

如此Q我们就不再需要在 XML 中显式?<bean/> q行 Bean 的配|。Spring 在容器初始化时将自动扫描 base-package 指定的包?qing)其子包下的所?class 文gQ所有标注了 @Repository 的类都将被注册ؓ(f) Spring Bean?/p>

Z?@Repository 只能标注?DAO cM呢?q是因ؓ(f)该注解的作用不只是将c识别ؓ(f) BeanQ同时它q能所标注的类中抛出的数据讉K异常装?Spring 的数据访问异常类型?Spring 本n提供了一个丰富的q且是与具体的数据访问技术无关的数据讉K异常l构Q用于封装不同的持久层框架抛出的异常Q得异常独立于底层的框架?/p>

Spring 2.5 ?@Repository 的基上增加了功能cM的额外三个注解:(x)@Component、@Service、@ConstrollerQ它们分别用于Y件系l的不同层次Q?/p>

•@Component 是一个泛化的概念Q仅仅表CZ个组?(Bean) Q可以作用在M层次?br /> •@Service 通常作用在业务层Q但是目前该功能?@Component 相同?br /> •@Constroller 通常作用在控制层Q但是目前该功能?@Component 相同?br /> ? q在cM使用 @Repository、@Component、@Service ?@Constroller 注解QSpring ?x)自动创建相应? BeanDefinition 对象Qƈ注册?ApplicationContext 中。这些类成?Spring 受管lg。这三个注解除了作用于不同Y件层ơ的c,其用方式与 @Repository 是完全相同的?/p>

另外Q除了上面的四个注解外,用户可以创徏自定义的注解Q然后在注解上标?@ComponentQ那么,该自定义注解便具有了与所 @Component 相同的功能。不q这个功能ƈ不常用?/p>

当一?Bean 被自动检到Ӟ?x)根据那个扫描器?BeanNameGenerator {略生成它的 bean 名称。默认情况下Q对于包?name 属性的 @Component、@Repository?@Service ?@ControllerQ会(x)? name 取g?Bean 的名字。如果这个注解不包含 name 值或是其他被自定义过滤器发现的组Ӟ默认 Bean 名称?x)是写开头的非限定类名。如果你不想使用默认 bean 命名{略Q可以提供一个自定义的命名策略。首先实?BeanNameGenerator 接口Q确认包含了一个默认的无参数构造方法。然后在配置扫描器时提供一个全限定cdQ如下所C:(x)

 <beans ...>
 <context:component-scan
    base-package="a.b" name-generator="a.SimpleNameGenerator"/>
 </beans>
 

与通过 XML 配置?Spring Bean 一P通过上述注解标识? BeanQ其默认作用域是"singleton"Qؓ(f)了配合这四个注解Q在标注 Bean 的同时能够指?Bean 的作用域QSpring 2.5 引入?@Scope 注解。用该注解时只需提供作用域的名称p了,如下所C:(x)

 @Scope("prototype")
 @Repository
 public class Demo { … }
 

如果你想提供一个自定义的作用域解析{略而不使用Z注解的方法,只需实现 ScopeMetadataResolver 接口Q确认包含一个默认的没有参数的构造方法。然后在配置扫描器时提供全限定类名:(x)

 <context:component-scan base-package="a.b"
 scope-resolver="footmark.SimpleScopeResolver" />
 


--------------------------------------------------------------------------------

回页?/p>

使用 @PostConstruct ?@PreDestroy 指定生命周期回调Ҏ(gu)

Spring Bean 是受 Spring IoC 容器理Q由容器q行初始化和销毁的Qprototype cd由容器初始化之后便不受容器管理)Q通常我们不需要关注容器对 Bean 的初始化和销毁操作,?Spring l过构造函数或者工厂方法创建的 Bean 是已经初始化完成ƈ立即可用的。然而在某些情况下,可能需要我们手工做一些额外的初始化或者销毁操作,q通常是针对一些资源的获取和释放操作? Spring 1.x 为此提供了两U方式供用户指定执行生命周期回调的方法?/p>

W一U方式是实现 Spring 提供的两个接口:(x)InitializingBean ?DisposableBean。如果希望在 Bean 初始化完成之后执行一些自定义操作Q则可以?Bean 实现 InitializingBean 接口Q该接口包含一? afterPropertiesSet() Ҏ(gu)Q容器在 Bean 讄了属性之后,自动调用该Ҏ(gu)Q如?Bean 实现? DisposableBean 接口Q则容器在销毁该 Bean 之前Q将调用该接口的 destroy() Ҏ(gu)。这U方式的~点是,?Bean cd?Spring 提供的接口,增加了代码与 Spring 框架的耦合度,因此不推荐用?/p>

W二U方式是?XML 文g中?<bean> ?init-method ?destroy-method 属性指定初始化之后和销毁之前的回调Ҏ(gu)Q代码无需实现M接口。这两个属性的取值是相应 Bean cM的初始化和销毁方法,Ҏ(gu)名Q意,但是Ҏ(gu)不能有参数。示例如下:(x)

 <bean id=”userService”
 class=”bookstore.service.UserService”
 init-method=”init” destroy-method=”destroy”>
    …
 </bean>
 

Spring 2.5 在保留以上两U方式的基础上,提供了对 JSR-250 的支持。JSR-250 规范定义了两个用于指定声明周期方法的注解Q@PostConstruct ? @PreDestroy。这两个注解使用非常单,只需分别他们标注于初始化之后执行的回调Ҏ(gu)或者销毁之前执行的回调Ҏ(gu)上。由于用了注解Q因此需 要配|相应的 Bean 后处理器Q亦卛_ XML 中增加如下一行:(x)

 <context:annotation-config />
 

比较上述三种指定生命周期回调Ҏ(gu)的方式,W一U是不徏议用的Q不但其用法不如后两U方式灵z,而且无Ş中增加了代码与框架的耦合度。后面两U方式开发者可以根据用习(fn)惯选择其中一U,但是最好不要؜合用,以免增加l护的难度?/p>


--------------------------------------------------------------------------------

回页?/p>

使用 @Required q行 Bean 的依赖检?/p>

依赖(g)查的作用是,判断l定 Bean 的相?Setter Ҏ(gu)是否都在实例化的时候被调用了。而不是判断字D|否已l存在g。Spring q行依赖(g)查时Q只?x)判断属性是否用了 Setter 注入。如果某个属性没有?Setter 注入Q即使是通过构造函数已lؓ(f)该属性注入了|Spring 仍然认ؓ(f)它没有执行注入,从而抛出异常。另外,Spring 只管是否通过 Setter 执行了注入,而对注入的值却没有M要求Q即使注入的 <null/>QSpring 也认为是执行了依赖注入?/p>

<bean> 标签提供?dependency-check 属性用于进行依赖检查。该属性的取值包括以下几U:(x)

•none -- 默认不执行依赖检查。可以在 <beans> 标签上?default-dependency-check 属性改变默认倹{?br /> •simple -- 对原始基本类型和集合cdq行(g)查?br /> •objects -- 对复杂类型进行检查(除了 simple 所(g)查类型之外的其他cdQ?br /> •all -- Ҏ(gu)有类型进行检查?br /> ? 版本使用 dependency-check 在配|文件中讄Q缺Ҏ(gu)_度较粗。?Spring2.0 提供?@Required 注解Q提供了更细_度的控制。@Required 注解只能标注?Setter Ҏ(gu)之上。因Z赖注入的本质是检?Setter Ҏ(gu)是否被调用了Q而不是真的去(g)查属性是否赋g以及(qing)赋了什么样的倹{如果将该注解标注在?setXxxx() cd的方法则被忽略?/p>

Z?Spring 能够处理该注解,需要激zȝ应的 Bean 后处理器。要Ȁz该后处理器Q只需?XML 中增加如下一行即可?/p>

 <context:annotation-config/>
 

当某个被标注?@Required ?Setter Ҏ(gu)没有被调用,?Spring 在解析的时候会(x)抛出异常Q以提醒开发者对相应属性进行设|?/p>


--------------------------------------------------------------------------------

回页?/p>

使用 @Resource、@Autowired ?@Qualifier 指定 Bean 的自动装配策?/p>

自动装配是指QSpring 在装?Bean 的时候,Ҏ(gu)指定的自动装配规则,某?Bean 所需要引用类型的 Bean 注入q来?lt;bean> 元素提供了一个指定自动装配类型的 autowire 属性,该属性有如下选项Q?/p>

•no -- 昑ּ指定不用自动装配?br /> •byName -- 如果存在一个和当前属性名字一致的 BeanQ则使用?Bean q行注入。如果名U匹配但是类型不匚wQ则抛出异常。如果没有匹配的cdQ则什么也不做?br /> •byType -- 如果存在一个和当前属性类型一致的 Bean ( 相同cd或者子cd )Q则使用?Bean q行注入。byType 能够识别工厂Ҏ(gu)Q即能够识别 factory-method 的返回类型。如果存在多个类型一致的 BeanQ则抛出异常。如果没有匹配的cdQ则什么也不做?br /> •constructor -- ?byType cMQ只不过它是针对构造函数注入而言的。如果当前没有与构造函数的参数cd匚w?BeanQ则抛出异常。用该U装配模式时Q优先匹配参数最多的构造函数?br /> •autodetect -- Ҏ(gu) Bean 的自省机制决定采?byType q是 constructor q行自动装配。如?Bean 提供了默认的构造函敎ͼ则采?byTypeQ否则采?constructor q行自动装配?br /> ? 使用 byType 或?constructor cd的自动装配的时候,自动装配也支持引用类型的数组或者用了泛型的集合,q样QSpring ׃(x)(g)查容器中所有类型匹配的 BeanQ组成集合或者数l后执行注入。对于用了泛型?Map cdQ如果键?String cdQ则 Spring 也会(x)自动执行装配Q将所有类型匹配的 Bean 作ؓ(f)|Bean 的名字作为键?/p>

我们可以l?<beans> 增加 default-autowire 属性,讄默认的自动封装策略。默认gؓ(f)"no"。如果用自动装配的同时Q也指定?property 或?constructor-arg 标签Q则昑ּ指定的值将覆盖自动装配的倹{目前的自动装不支持简单类型,比如基本cd、String、ClassQ以?qing)它们的数组cd?/p>

在按cd匚w的时?( 可能?byType、constructor、autodetect)Q同一个类型可能存在多?BeanQ如果被注入的属性是数组、集合或?MapQ这可能没有问题Q但是如果只是简单的引用cdQ则?x)抛出异常。解x法有如下几种Q?/p>

•取消?Bean 的自动装配特性,使用昑ּ的注入。我们可能不希望某个 Bean 被当作其?Bean 执行自动装时的候选对象,我们可以l该 <bean> 增加 autowire-candidate="false"?autowire-candidate 属性和 autowire 属性相互独立,互不相干。某?Bean 可以?autowire-candidate 讄?falseQ同时?autowire Ҏ(gu)? 另外Q我们可以设|?<beans> ?default-autowire-candidates 属性,可以在该属性中指定可以用于自动装配候?Bean 的匹配模式,比如 default-autowire-candidates="*serv,*dao"Q这表示所有名字以 serv 或?dao l尾?Bean 被列为候选,其他则忽略,相当于其?Bean 都指定ؓ(f) autowire-candidate="false"Q此时可以显式ؓ(f) <bean> 指定 autowire-candidate="true"。在 <bean> 上指定的讄要覆? <beans> 上指定的讄?br /> •如果在多个类型相同的 Bean 中有首选的 BeanQ那么可以将?<bean> ?primary 属性设|ؓ(f) "true" Q这栯动装配时便优先用该 Bean q行装配。此时不能将 autowire-candidate 设ؓ(f) false?br /> •如果使用的是 Java 5 以上版本Q可以用注解进行更l粒度的控制?br /> 使用 @Autowired ?@Qualifier 注解执行自动装配

使用 @Autowired 注解q行装配Q只能是Ҏ(gu)cdq行匚w。@Autowired 注解可以用于 Setter Ҏ(gu)、构造函数、字D,甚至普通方法,前提是方法必L臛_一个参数。@Autowired 可以用于数组和用泛型的集合cd。然?Spring ?x)将容器中所有类型符合的 Bean 注入q来。@Autowired 标注作用?Map cdӞ如果 Map ?key ?String cdQ则 Spring ?x)将容器中所有类型符?Map ?value 对应的类型的 Bean 增加q来Q用 Bean ?id ?name 作ؓ(f) Map ?key?/p>

@Autowired 标注作用于普通方法时Q会(x)产生一个副作用Q就是在容器初始化该 Bean 实例的时候就?x)调用该?gu)。当Ӟ前提是执行了自动装配Q对于不满装配条g的情况,该方法也不会(x)被执行?/p>

当标注了 @Autowired 后,自动注入不能满Q则?x)抛出异常。我们可以给 @Autowired 标注增加一? required=false 属性,以改变这个行为。另外,每一个类中只能有一个构造函数的 @Autowired.required() 属性ؓ(f) true。否则就出问题了。如果用 @Autowired 同时标注了多个构造函敎ͼ那么QSpring 采用贪心算法匹配构造函?( 构造函数最? )?/p>

@Autowired q有一个作用就是,如果其标注?BeanFactory cd、ApplicationContext cd、ResourceLoader cd、ApplicationEventPublisher cd、MessageSource cd上,那么 Spring ?x)自动注入这些实现类的实例,不需要额外的操作?/p>

当容器中存在多个 Bean 的类型与需要注入的相同Ӟ注入不能执行,我们可以l?@Autowired 增加一个候选|做法是在 @Autowired 后面增加一?@Qualifier 标注Q提供一?String cd的g为候选的 Bean 的名字。D例如下:(x)

 @Autowired(required=false)
 @Qualifier("ppp")
 public void setPerson(person p){}
 

@Qualifier 甚至可以作用于方法的参数 ( 对于Ҏ(gu)只有一个参数的情况Q我们可以将 @Qualifer 标注攄在方法声明上面,但是推荐攄在参数前?)QD例如下:(x)

 @Autowired(required=false)
 public void sayHello(@Qualifier("ppp")Person p,String name){}
 

我们可以在配|文件中指定某个 Bean ?qualifier 名字Q方法如下:(x)

 <bean id="person" class="footmark.spring.Person">
    <qualifier value="ppp"/>
 </bean>
 

如果没有明确指定 Bean ?qualifier 名字Q那么默认名字就?Bean 的名字。通常Qqualifier 应该是有业务含义的,例如 "domain"Q?persistent" {,而不应该是类?"person" 方式?/p>

我们q可以将 @Qualifier 标注在集合类型上Q那么所?qualifier 名字与指定值相同的 Bean 都将被注入进来?/p>

最后,配置文g中需要指定每一个自定义注解的属性倹{我们可以?<meta> 标签来代?<qualifier/> 标签Q如?<meta> 标签?<qualifier/> 标签同时出现Q那么优先? <qualifier> 标签。如果没?<qualifier> 标签Q那么会(x)?<meta> 提供的键值对来封?<qualifier> 标签。示例如下:(x)

 <bean class="footmark.HelloWorld">
 <qualifier type="MovieQualifier">
 <attribute key="format" value="VHS"/>
 <attribute key="genre" value="Comedy"/>
 </qualifier>
 </bean>
 <bean class="footmark.HelloWorld">
 <meta key="format" value="DVD"/>
 <meta key="genre" value="Action"/>
 </bean>
 

@Autowired 注解对应的后处理注册与前面相|只需在配|文件中增加如下一行即可:(x)

 <context:annotation-config/>
 

如果 @Autowired 注入的是 BeanFactory、ApplicationContext、ResourceLoader {系l类型,那么则不需?@QualifierQ此时即使提供了 @Qualifier 注解Q也会(x)被忽略;而对于自定义cd的自动装配,如果使用? @Qualifier 注解q且没有名字与之匚w?BeanQ则自动装配匚wp|?/p>

使用 JSR-250 中的 @Resource ?@Qualifier 注解

如果希望Ҏ(gu) name 执行自动装配Q那么应该?JSR-250 提供?@Resource 注解Q而不应该使用 @Autowired ?@Qualifier 的组合?/p>

@Resource 使用 byName 的方式执行自动封装。@Resource 标注可以作用于带一个参数的 Setter Ҏ(gu)、字D,以及(qing)带一个参数的普通方法上。@Resource 注解有一?name 属性,用于指定 Bean 在配|文件中对应的名字。如果没有指? name 属性,那么默认值就是字D|者属性的名字。@Resource ?@Qualifier 的配合虽然仍然成立,但是 @Qualifier 对于 @Resource 而言Q几乎与 name 属性等效?/p>

如果 @Resource 没有指定 name 属性,那么使用 byName 匚wp|后,?x)退而?byType l箋匚wQ如果再p|Q则抛出异常。在没有?@Resource 注解昑ּ指定 name 属性的前提下,如果其标注?BeanFactory cd、ApplicationContext cd、ResourceLoader cd、ApplicationEventPublisher cd、MessageSource cd上,那么 Spring ?x)自动注入这些实现类的实例,不需要额外的操作。此?name 属性不需要指?( 或者指定ؓ(f)"")Q否则注入失败;如果使用?@QualifierQ则该注解将被忽略。而对于用戯定义cd的注入,@Qualifier ? name {h(hun)Qƈ且不被忽略?/p>

<bean> ?primary ?autowire-candidate 属性对 @Resource、@Autowired 仍然有效?/p>


--------------------------------------------------------------------------------

回页?/p>

使用 @Configuration ?@Bean q行 Bean 的声?/p>

虽然 2.0 版本发布以来QSpring 陆箋提供了十多个注解Q但是提供的q些注解只是Z在某些情况下?XML 的配|,q要取? XML 配置方式。这一点可以从 Spring IoC 容器的初始化cd以看出:(x)ApplicationContext 接口的最常用的实现类? ClassPathXmlApplicationContext ?FileSystemXmlApplicationContextQ以?qing)面? Portlet ?XmlPortletApplicationContext 和面?web ? XmlWebApplicationContextQ它们都是面?XML 的。Spring 3.0 新增了另外两个实现类QAnnotationConfigApplicationContext ? AnnotationConfigWebApplicationContext。从名字便可以看出,它们是ؓ(f)注解而生Q直接依赖于注解作ؓ(f)容器配置信息? 源的 IoC 容器初始化类。由?AnnotationConfigWebApplicationContext ? AnnotationConfigApplicationContext ?web 版本Q其用法与后者相比几乎没有什么差别,因此本文以 AnnotationConfigApplicationContext Zq行讲解?/p>

AnnotationConfigApplicationContext 搭配?@Configuration ?@Bean 注解Q自此,XML 配置方式不再?Spring IoC 容器的唯一配置方式。两者在一定范围内存在着竞争的关p,但是它们在大多数情况下还是相互协作的关系Q两者的l合使得 Spring IoC 容器的配|更单,更强大?/p>

之前Q我们将配置信息集中写在 XML 中,如今使用注解Q配|信息的载体?XML 文g转移C Java cM。我们通常用于存N|信息的cȝcd?“Config” l尾Q比? AppDaoConfig.java、AppServiceConfig.java {等。我们需要在用于指定配置信息的类上加? @Configuration 注解Q以明确指出该类?Bean 配置的信息源。ƈ?Spring Ҏ(gu)?Configuration 的类有如下要求:(x)

•配置cM能是 final 的;
•配置cM能是本地化的Q亦即不能将配置cd义在其他cȝҎ(gu)内部Q?br /> •配置cdL一个无参构造函数?br /> AnnotationConfigApplicationContext 配|类中标注了 @Bean 的方法的q回D别ؓ(f) Spring BeanQƈ注册到容器中Q受 IoC 容器理。@Bean 的作用等价于 XML 配置中的 <bean/> 标签。示例如下:(x)

 @Configuration
 public class BookStoreDaoConfig{
    @Bean
    public UserDao userDao(){ return new UserDaoImpl();}
    @Bean
    public BookDao bookDao(){return new BookDaoImpl();}
 }
 

Spring 在解析到以上文gӞ识别出标注 @Bean 的所有方法,执行之,q将Ҏ(gu)的返回?( q里?UserDaoImpl ? BookDaoImpl 对象 ) 注册?IoC 容器中。默认情况下QBean 的名字即为方法名。因此,与以上配|等L(fng) XML 配置如下Q?/p>

 <bean id=”userDao” class=”bookstore.dao.UserDaoImpl”/>
 <bean id=”bookDao” class=”bookstore.dao.BookDaoImpl”/>
 

@Bean h以下四个属性:(x)

•name -- 指定一个或者多?Bean 的名字。这{h(hun)?XML 配置?<bean> ?name 属性?br /> •initMethod -- 容器在初始化?Bean 之后Q会(x)调用该属性指定的Ҏ(gu)。这{h(hun)?XML 配置?<bean> ?init-method 属性?br /> •destroyMethod -- 该属性与 initMethod 功能怼Q在容器销?Bean 之前Q会(x)调用该属性指定的Ҏ(gu)。这{h(hun)?XML 配置?<bean> ?destroy-method 属性?br /> •autowire -- 指定 Bean 属性的自动装配{略Q取值是 Autowire cd的三个静态属性。Autowire.BY_NAMEQAutowire.BY_TYPEQAutowire.NO。与 XML 配置中的 autowire 属性的取值相比,q里了 constructorQ这是因?constructor 在这里已l没有意义了?br /> @Bean 没有直接提供指定作用域的属性,可以通过 @Scope 来实现该功能Q关?@Scope 的用法已在上文列举?/p>

下面讲解Z注解的容器初始化。AnnotationConfigApplicationContext 提供了三个构造函数用于初始化容器?/p>

•AnnotationConfigApplicationContext()Q该构造函数初始化一个空容器Q容器不包含M Bean 信息Q需要在E后通过调用?register() Ҏ(gu)注册配置c,q调?refresh() Ҏ(gu)h容器?br /> •AnnotationConfigApplicationContext(Class<?>... annotatedClasses)Q这是最常用的构造函敎ͼ通过涉?qing)到的配|类传递给该构造函敎ͼ以实现将相应配置cM?Bean 自动注册到容器中?br /> •AnnotationConfigApplicationContext(String... basePackages)Q该构造函C(x)自动扫描以给定的包及(qing)其子包下的所有类Qƈ自动识别所有的 Spring BeanQ将其注册到容器中。它不但识别标注 @Configuration 的配|类q正解析,而且同样能识别? @Repository、@Service、@Controller、@Component 标注的类?br /> 除了使用上面W三U类型的构造函数让容器 自动扫描 Bean 的配|信息以外,AnnotationConfigApplicationContext q提供了 scan() Ҏ(gu)Q其功能与上面也cMQ该Ҏ(gu)主要用在容器初始化之后动态增?Bean 臛_器中。调用了该方法以后,通常需要立x动调?refresh() h容器Q以让变更立即生效?/p>

需要注意的是,AnnotationConfigApplicationContext 在解析配|类Ӟ?x)将配置c自w注册ؓ(f)一? BeanQ因?@Configuration 注解本n定义时被 @Component 标注了。因此可以说Q一?@Configuration 同时也是一?@Component。大多数情况下,开发者用不到?BeanQƈ且在理想情况下,?Bean 应该是对开发者透明的。@Configuration 的定义如下所C:(x)

 @Target({ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Component
 public @interface Configuration {
 String value() default "";
 }
 

在一般的目中,Zl构清晰Q通常?x)根据Y件的模块或者结构定义多?XML 配置文gQ然后再定义一个入口的配置文gQ该文g使用 <import/> 其他的配置文gl织h。最后只需该文g传给 ClassPathXmlApplicationContext 的构造函数即可。针对基于注解的配置QSpring 也提供了cM的功能,只需定义一个入口配|类Qƈ在该cM使用 @Import 注解引入其他的配|类卛_Q最后只需要将该入口类传递给 AnnotationConfigApplicationContext。具体示例如下:(x)

 @Configuration
 @Import({BookStoreServiceConfig.class,BookStoreDaoConfig.class})
 public class BookStoreConfig{ … }
 


--------------------------------------------------------------------------------

回页?/p>

混合使用 XML 与注解进?Bean 的配|?/p>

设计 @Configuration ?@Bean 的初Pq不是ؓ(f)了完全取?XMLQ而是Z?XML 之外多一U可行的选择。由? Spring 自发布以来,Spring 开发小l便不断?XML 配置Q?XML 配置方式已经非常成熟Q加?Spring 2.0 以后出现了一pd命名I间的支持,使得 XML 配置方式成ؓ(f)了用简单、功能强大的 Bean 定义方式。而且QXML 配置的一些高U功能目前还没有相关注解能够直接支持。因此,在目前的多数目中,要么使用Ua(b)?XML 配置方式q行 Bean 的配|,要么使用以注解ؓ(f)主,XML 的配|方式进?Bean 的配|?/p>

之所以会(x)出现两者共存的情况Q主要归lؓ(f)三个原因Q其一Q目前绝大多数采?Spring q行开发的目Q几乎都是基?XML 配置方式的,Spring 在引入注解的同时Q必M证注解能够与 XML 和谐共存Q这是前提;其二Q由于注解引入较晚,因此功能也没有发展多q的 XML 强大Q因此,对于复杂的配|,注解q很隄当一面,在一D|间内仍然需?XML 的配合才能解决问题。除此之外,Spring ?Bean 的配|方式与 Spring 核心模块之间是解耦的Q因此,改变配置方式?Spring 的框架自w是透明的。Spring 可以通过使用 Bean 后处理器 (BeanPostProcessor) 非常方便的增加对于注解的支持。这在技术实C非常Ҏ(gu)的事情?/p>

要用؜合配|方式,首先需要判断以哪一U配|方式ؓ(f)丅R对q个问题的不同回{将?x)直接?jing)响到实现的方式。然而大可不必ؓ(f)此伤脑筋Q因Z论是? XML ZQ还是以注解ZQ配|方式都是简单而且Ҏ(gu)理解的。这里不存在错误的决定,因ؓ(f)仅仅是表现方式不一栗我们首先假设以 XML 配置Z的情c(din)?/p>

对于已经存在的大型项目,可能初期是以 XML q行 Bean 配置的,后箋逐渐加入了注解的支持Q这时我们只需?XML 配置文g中将? @Configuration 标注的类定义为普通的 <bean>Q同时注册处理注解的 Bean 后处理器卛_。示例如下:(x)

 // 假设存在如下?@Configuration c:(x)
 package bookstore.config;
 import bookstore.dao.*;
 @Configuration
 public class MyConfig{
 @Bean
    public UserDao userDao(){
        return new UserDaoImpl();
    }
 }
此时Q只需?XML 中作如下声明卛_Q?br />  <beans … >
    ……
    <context:annotation-config />
    <bean class=”demo.config.MyConfig”/>
 </beans>
 

׃启用了针Ҏ(gu)解的 Bean 后处理器Q因此在 ApplicationContext 解析?MyConfig cLQ会(x)发现该类标注? @Configuration 注解Q随后便?x)处理该cM标注 @Bean 的方法,这些方法的q回值注册ؓ(f)容器ȝ Bean?/p>

对于以上的方式,如果存在多个标注?@Configuration 的类Q则需要在 XML 文g中逐一列出。另一U方式是使用前面提到的自动扫描功能,配置如下Q?/p>

 <context:component-scan base-package=”bookstore.config” />
 

如此QSpring 扫描所?demo.config 包及(qing)其子包中的类Q识别所有标C @Component、@Controller、@Service、@Repository 注解的类Q由?@Configuration 注解本n也用 @Component 标注了,Spring 能够识别出 @Configuration 标注cdƈ正确解析之?/p>

对于以注解ؓ(f)中心的配|方式,只需使用 @ImportResource 注解引入存在?XML 卛_Q如下所C:(x)

 @Configuration
 @ImportResource(“classpath:/bookstore/config/spring-beans.xml”)
 public class MyConfig{
……
 }
 // 容器的初始化q程和纯_的以配|ؓ(f)中心的方式一_(d)(x)
 AnnotationConfigApplicationContext ctx =
              new AnnotationConfigApplicationContext(MyConfig.class);
……

西瓜 2011-04-14 10:01 发表评论
]]>
3Qaop实现,2.0中pointcut的定?/title><link>http://m.tkk7.com/ashutc/archive/2010/11/02/336777.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Tue, 02 Nov 2010 03:50:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2010/11/02/336777.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/336777.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2010/11/02/336777.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/336777.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/336777.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;">在Spring </span><span style="color: #000000;">2</span><span style="color: #000000;">.0中,Pointcut的定义包括两个部分:(x)Pointcut表示?expression)和Pointcut{֐(signature)。让我们先看看execution表示式的格式Q?br /> java 代码<br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. execution(modifier</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern</span><span style="color: #000000;">?</span><span style="color: #000000;"><br />    </span><span style="color: #000000;">2</span><span style="color: #000000;">.           ret</span><span style="color: #000000;">-</span><span style="color: #000000;">type</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern<br />    </span><span style="color: #000000;">3</span><span style="color: #000000;">.           declaring</span><span style="color: #000000;">-</span><span style="color: #000000;">type</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern</span><span style="color: #000000;">?</span><span style="color: #000000;"><br />    </span><span style="color: #000000;">4</span><span style="color: #000000;">.           name</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern(param</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern)<br />    </span><span style="color: #000000;">5</span><span style="color: #000000;">.           </span><span style="color: #0000ff;">throws</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern</span><span style="color: #000000;">?</span><span style="color: #000000;">)<br /> <br /> <br /> 括号中各个pattern分别表示修饰W匹配(modifier</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern</span><span style="color: #000000;">?</span><span style="color: #000000;">Q、返回值匹配(ret</span><span style="color: #000000;">-</span><span style="color: #000000;">type</span><span style="color: #000000;">-</span><span style="color: #000000;">patternQ、类路径匚wQdeclaring</span><span style="color: #000000;">-</span><span style="color: #000000;">type</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern</span><span style="color: #000000;">?</span><span style="color: #000000;">Q、方法名匚wQname</span><span style="color: #000000;">-</span><span style="color: #000000;">patternQ、参数匹配((param</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern)Q、异常类型匹配(</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern</span><span style="color: #000000;">?</span><span style="color: #000000;">Q,其中后面跟着“</span><span style="color: #000000;">?</span><span style="color: #000000;">”的是可选项?br /> 在各个pattern中可以?#8220;</span><span style="color: #000000;">*</span><span style="color: #000000;">”来表C匹配所有。在(param</span><span style="color: #000000;">-</span><span style="color: #000000;">pattern)中,可以指定具体的参数类型,多个参数间用“,”隔开Q各个也可以?#8220;</span><span style="color: #000000;">*</span><span style="color: #000000;">”来表C匹配Q意类型的参数Q如(String)表示匚w一个String参数的方法;(</span><span style="color: #000000;">*</span><span style="color: #000000;">,String)表示匚w有两个参数的Ҏ(gu)Q第一个参数可以是LcdQ而第二个参数是StringcdQ可以用(..)表示零个或多个Q意参数?br /> 现在来看看几个例子:(x)<br /> </span><span style="color: #000000;">1</span><span style="color: #000000;">Qexecution(</span><span style="color: #000000;">*</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">(..))<br /> 表示匚w所有方?br /> </span><span style="color: #000000;">2</span><span style="color: #000000;">Qexecution(</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;"> com. savage.service.UserService.</span><span style="color: #000000;">*</span><span style="color: #000000;">(..))<br /> 表示匚wcom.savage.server.UserService中所有的公有Ҏ(gu)<br /> </span><span style="color: #000000;">3</span><span style="color: #000000;">Qexecution(</span><span style="color: #000000;">*</span><span style="color: #000000;"> com.savage.server..</span><span style="color: #000000;">*</span><span style="color: #000000;">.</span><span style="color: #000000;">*</span><span style="color: #000000;">(..))<br /> 表示匚wcom.savage.server包及(qing)其子包下的所有方?br /> 除了execution表示式外Q还有within?/span><span style="color: #0000ff;">this</span><span style="color: #000000;">、target、args{Pointcut表示式。一个Pointcut定义由Pointcut表示式和Pointcut{֐l成Q例如:(x)<br /> java 代码<br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. </span><span style="color: #008000;">//</span><span style="color: #008000;">Pointcut表示?/span><span style="color: #008000;"><br /> </span><span style="color: #000000;">   </span><span style="color: #000000;">2</span><span style="color: #000000;">. @Pointcut(</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* com.savage.aop.MessageSender.*(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />    </span><span style="color: #000000;">3</span><span style="color: #000000;">. </span><span style="color: #008000;">//</span><span style="color: #008000;">Point{֐</span><span style="color: #008000;"><br /> </span><span style="color: #000000;">   </span><span style="color: #000000;">4</span><span style="color: #000000;">. </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> log(){}                             <br /> <br /> <br /> 然后要用所定义的PointcutӞ可以指定Pointcut{֐Q如<br /> java 代码<br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. @Before(</span><span style="color: #000000;">"</span><span style="color: #000000;">og()</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br /> <br /> <br /> 上面的定义等同与Q?br /> java 代码<br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. @Before(</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* com.savage.aop.MessageSender.*(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br /> <br /> <br /> Pointcut定义Ӟq可以?/span><span style="color: #000000;">&&</span><span style="color: #000000;">?/span><span style="color: #000000;">||</span><span style="color: #000000;">?/span><span style="color: #000000;">!</span><span style="color: #000000;">q算Q如Q?br /> java 代码<br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. @Pointcut(</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* com.savage.aop.MessageSender.*(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />    </span><span style="color: #000000;">2</span><span style="color: #000000;">. </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> logSender(){}<br />    </span><span style="color: #000000;">3</span><span style="color: #000000;">.<br />    </span><span style="color: #000000;">4</span><span style="color: #000000;">. @Pointcut(</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* com.savage.aop.MessageReceiver.*(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />    </span><span style="color: #000000;">5</span><span style="color: #000000;">. </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> logReceiver(){}<br />    </span><span style="color: #000000;">6</span><span style="color: #000000;">.<br />    </span><span style="color: #000000;">7</span><span style="color: #000000;">. @Pointcut(</span><span style="color: #000000;">"</span><span style="color: #000000;">logSender() || logReceiver()</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />    </span><span style="color: #000000;">8</span><span style="color: #000000;">. </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> logMessage(){}<br /> <br /> <br /> q个例子中,logMessage()匹配Q何MessageSender和MessageReceiver中的MҎ(gu)?br /> q可以将一些公用的Pointcut攑ֈ一个类中,以供整个应用E序使用Q如Q?br /> java 代码<br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. </span><span style="color: #0000ff;">package</span><span style="color: #000000;"> com.savage.aop;<br />    </span><span style="color: #000000;">2</span><span style="color: #000000;">.<br />    </span><span style="color: #000000;">3</span><span style="color: #000000;">. </span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.aspectj.lang.annotation.</span><span style="color: #000000;">*</span><span style="color: #000000;">;<br />    </span><span style="color: #000000;">4</span><span style="color: #000000;">.<br />    </span><span style="color: #000000;">5</span><span style="color: #000000;">. </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Pointcuts {<br />    </span><span style="color: #000000;">6</span><span style="color: #000000;">.    @Pointcut(</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* *Message(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />    </span><span style="color: #000000;">7</span><span style="color: #000000;">.    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> logMessage(){}<br />    </span><span style="color: #000000;">8</span><span style="color: #000000;">.<br />    </span><span style="color: #000000;">9</span><span style="color: #000000;">.    @Pointcut(</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* *Attachment(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />   </span><span style="color: #000000;">10</span><span style="color: #000000;">.    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> logAttachment(){}<br />   </span><span style="color: #000000;">11</span><span style="color: #000000;">.<br />   </span><span style="color: #000000;">12</span><span style="color: #000000;">.    @Pointcut(</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* *Service.*(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />   </span><span style="color: #000000;">13</span><span style="color: #000000;">.    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> auth(){}<br />   </span><span style="color: #000000;">14</span><span style="color: #000000;">. }<br /> <br /> <br /> 在用这些PointcutӞ指定完整的类名加上Pointcut{֐可以了Q如Q?br /> java 代码<br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. </span><span style="color: #0000ff;">package</span><span style="color: #000000;"> com.savage.aop;<br />    </span><span style="color: #000000;">2</span><span style="color: #000000;">.<br />    </span><span style="color: #000000;">3</span><span style="color: #000000;">. </span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.aspectj.lang.JoinPoint;<br />    </span><span style="color: #000000;">4</span><span style="color: #000000;">. </span><span style="color: #0000ff;">import</span><span style="color: #000000;"> org.aspectj.lang.annotation.</span><span style="color: #000000;">*</span><span style="color: #000000;">;<br />    </span><span style="color: #000000;">5</span><span style="color: #000000;">.<br />    </span><span style="color: #000000;">6</span><span style="color: #000000;">. @Aspect<br />    </span><span style="color: #000000;">7</span><span style="color: #000000;">. </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> LogBeforeAdvice {<br />    </span><span style="color: #000000;">8</span><span style="color: #000000;">.    @Before(</span><span style="color: #000000;">"</span><span style="color: #000000;">com.sagage.aop.Pointcuts.logMessage()</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />    </span><span style="color: #000000;">9</span><span style="color: #000000;">.    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> before(JoinPoint joinPoint) {<br />   </span><span style="color: #000000;">10</span><span style="color: #000000;">.       System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">Logging before </span><span style="color: #000000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> joinPoint.getSignature().getName());<br />   </span><span style="color: #000000;">11</span><span style="color: #000000;">.    }<br />   </span><span style="color: #000000;">12</span><span style="color: #000000;">. }<br /> <br /> <br /> 当基于XML Sechma实现AdviceӞ如果Pointcut需要被重用Q可以?/span><span style="color: #000000;"><</span><span style="color: #000000;">aop:pointcut</span><span style="color: #000000;">></</span><span style="color: #000000;">aop:pointcut</span><span style="color: #000000;">></span><span style="color: #000000;">来声明PointcutQ然后在需要用这个Pointcut的地方,用pointcut</span><span style="color: #000000;">-</span><span style="color: #000000;">ref引用p了,如:(x)<br /> xml 代码<br />  <br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. </span><span style="color: #000000;"><</span><span style="color: #000000;">aop:config</span><span style="color: #000000;">></span><span style="color: #000000;">  <br />    </span><span style="color: #000000;">2</span><span style="color: #000000;">.     </span><span style="color: #000000;"><</span><span style="color: #000000;">aop:pointcut id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">log</span><span style="color: #000000;">"</span><span style="color: #000000;">   <br />    </span><span style="color: #000000;">3</span><span style="color: #000000;">.           expression</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">execution(* com.savage.simplespring.bean.MessageSender.*(..))</span><span style="color: #000000;">"</span><span style="color: #000000;">/></span><span style="color: #000000;">  <br />    </span><span style="color: #000000;">4</span><span style="color: #000000;">.     </span><span style="color: #000000;"><</span><span style="color: #000000;">aop:aspect id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">logging</span><span style="color: #000000;">"</span><span style="color: #000000;"> ref</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">logBeforeAdvice</span><span style="color: #000000;">"</span><span style="color: #000000;">></span><span style="color: #000000;">  <br />    </span><span style="color: #000000;">5</span><span style="color: #000000;">.         </span><span style="color: #000000;"><</span><span style="color: #000000;">aop:before pointcut</span><span style="color: #000000;">-</span><span style="color: #000000;">ref</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">log</span><span style="color: #000000;">"</span><span style="color: #000000;"> method</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">before</span><span style="color: #000000;">"</span><span style="color: #000000;">/></span><span style="color: #000000;">  <br />    </span><span style="color: #000000;">6</span><span style="color: #000000;">.         </span><span style="color: #000000;"><</span><span style="color: #000000;">aop:after</span><span style="color: #000000;">-</span><span style="color: #000000;">returning pointcut</span><span style="color: #000000;">-</span><span style="color: #000000;">ref</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">log</span><span style="color: #000000;">"</span><span style="color: #000000;"> method</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">afterReturning</span><span style="color: #000000;">"</span><span style="color: #000000;">/></span><span style="color: #000000;">  <br />    </span><span style="color: #000000;">7</span><span style="color: #000000;">.     </span><span style="color: #000000;"></</span><span style="color: #000000;">aop:aspect</span><span style="color: #000000;">></span><span style="color: #000000;">  <br />    </span><span style="color: #000000;">8</span><span style="color: #000000;">. </span><span style="color: #000000;"></</span><span style="color: #000000;">aop:config</span><span style="color: #000000;">></span><span style="color: #000000;">  <br /> <br /> <br /> </span></div> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <img src ="http://m.tkk7.com/ashutc/aggbug/336777.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2010-11-02 11:50 <a href="http://m.tkk7.com/ashutc/archive/2010/11/02/336777.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2:aop实现-spring2.0中的aop实现http://m.tkk7.com/ashutc/archive/2010/11/02/336776.html西瓜西瓜Tue, 02 Nov 2010 03:49:00 GMThttp://m.tkk7.com/ashutc/archive/2010/11/02/336776.htmlhttp://m.tkk7.com/ashutc/comments/336776.htmlhttp://m.tkk7.com/ashutc/archive/2010/11/02/336776.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/336776.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/336776.html在Spring 2.0中,除了传统的通过实现AOP AIP的方式来实现Advice之外Q还提供了两U更加简便的方式来实现AdviceQ?Q基于XML Schema...  阅读全文

西瓜 2010-11-02 11:49 发表评论
]]>
1:aop实现-advicehttp://m.tkk7.com/ashutc/archive/2010/11/02/336775.html西瓜西瓜Tue, 02 Nov 2010 03:47:00 GMThttp://m.tkk7.com/ashutc/archive/2010/11/02/336775.htmlhttp://m.tkk7.com/ashutc/comments/336775.htmlhttp://m.tkk7.com/ashutc/archive/2010/11/02/336775.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/336775.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/336775.html在Spring1.2或之前的版本中,实现AOP的传l方式就是通过实现Spring的AOP API来定义AdviceQƈ讄代理对象。SpringҎ(gu)Adivce加入C务流E的时机?..  阅读全文

西瓜 2010-11-02 11:47 发表评论
]]>
spring 3.0 mvchttp://m.tkk7.com/ashutc/archive/2010/10/27/336249.html西瓜西瓜Wed, 27 Oct 2010 01:43:00 GMThttp://m.tkk7.com/ashutc/archive/2010/10/27/336249.htmlhttp://m.tkk7.com/ashutc/comments/336249.htmlhttp://m.tkk7.com/ashutc/archive/2010/10/27/336249.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/336249.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/336249.html RestController.java
package cn.yu.test;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class RestController {

    
public RestController() {

    }

    @RequestMapping(value 
= "/login/{user}", method = RequestMethod.GET)
    
public ModelAndView myMethod(HttpServletRequest request, HttpServletResponse response, @PathVariable("user") String user, ModelMap modelMap) throws Exception {
        modelMap.put(
"loginUser", user);
        
return new ModelAndView("/hello", modelMap);
    }

    @RequestMapping(value 
= "/welcome", method = RequestMethod.GET)
    
public String registjsp() {
        
return "/welcome";
    }

    @RequestMapping(value 
= "/welcomehtml", method = RequestMethod.GET)
    
public String registPost() {
        
return "redirect:/jsp/welcomehtml.html";
    }
}

spring-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans   
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
           http://www.springframework.org/schema/context   
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    
<!-- 自动扫描beanQ把作了注解的类转换为bean -->
    
<context:component-scan base-package="cn.yu.test" />

    
<!-- 启动Spring MVC的注解功能,完成h和注解POJO的映?nbsp;-->
    
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />



    
<!-- Ҏ(gu)型视囑֐U的解析Q在h时模型视囑֐U添加前后缀 -->
    
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/jsp"  p:suffix=".jsp"/>
    
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8" />

</beans> 


web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet-mapping>
        
<servlet-name>default</servlet-name>
        
<url-pattern>*.js</url-pattern>
    
</servlet-mapping>
    
<servlet-mapping>
        
<servlet-name>default</servlet-name>
        
<url-pattern>*.css</url-pattern>
    
</servlet-mapping>

    
<servlet-mapping>
        
<servlet-name>default</servlet-name>
        
<url-pattern>*.gif</url-pattern>
    
</servlet-mapping>

    
<servlet-mapping>
        
<servlet-name>default</servlet-name>
        
<url-pattern>*.jpg</url-pattern>
    
</servlet-mapping>
    
<servlet-mapping>
        
<servlet-name>default</servlet-name>
        
<url-pattern>*.html</url-pattern>
    
</servlet-mapping>
    
<servlet>
        
<servlet-name>spring</servlet-name>
        
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        
<load-on-startup>1</load-on-startup>
    
</servlet>
    
<servlet-mapping>
        
<servlet-name>spring</servlet-name>
        
<url-pattern>/</url-pattern>
        
<!-- url配置?/span>/Q不带文件后~Q会(x)造成其它静态文?jsQcss{?不能讉K。如配ؓ(f)*.doQ则不媄(jing)响静态文件的

讉K 
-->
    
</servlet-mapping>
</web-app>

jsp文g?个网c(din)hello.jsp,welcome.jsp,welcomehtml.html
















西瓜 2010-10-27 09:43 发表评论
]]>
no matching editors or conversion strategyQ配|事物时出现的错误)http://m.tkk7.com/ashutc/archive/2010/09/27/333020.html西瓜西瓜Mon, 27 Sep 2010 01:35:00 GMThttp://m.tkk7.com/ashutc/archive/2010/09/27/333020.htmlhttp://m.tkk7.com/ashutc/comments/333020.htmlhttp://m.tkk7.com/ashutc/archive/2010/09/27/333020.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/333020.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/333020.html
Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy5 implementing java.lang.Runnable,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [java.util.TimerTask] for property 'timerTask': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:
231)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:
138)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:
386)
     
42 more



<tx:annotation-driven transaction-manager="txManager"/>
更改?br />
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

表示proxy代理的是c而不是接口?br />

    <!-- Tranceaction -->
    
<bean id="txManager"
        
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
<property name="dataSource">
            
<ref local="dataSource" />
        
</property>
    
</bean>

错误?

Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
原因?
~少包:(x)cglib-2.1.3.jar





























西瓜 2010-09-27 09:35 发表评论
]]>
用Spring提供的JUnit框架扩展对DAO或Service层进行单元测?/title><link>http://m.tkk7.com/ashutc/archive/2010/09/06/331175.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Mon, 06 Sep 2010 03:02:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2010/09/06/331175.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/331175.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2010/09/06/331175.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/331175.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/331175.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;">一、Spring提供的JUnit框架扩展Q?br /> <br />    </span><span style="color: #000000;">1</span><span style="color: #000000;">. AbstractSpringContextTestsQspring中用spring上下文测试的Junit扩展c,我们一般不?x)用这个类来进行单元测试,它是spring内部设计使用到的c?br />    </span><span style="color: #000000;">2</span><span style="color: #000000;">. AbstractDependencyInjectionSpringContextTestsQ这是AbstractSpringContextTests的直接子c,支持依赖spring上下文的试c,q个cM支持事务?br />    </span><span style="color: #000000;">3</span><span style="color: #000000;">. AbstractTransactionalSpringContextTestsQ这?nbsp;AbstractDependencyInjectionSpringContextTests的直接子c,q个cM般应用在事务相关的测试中Q一旦完成每个测试它?yu)׃?x)正常地回滚事务,不会(x)真正更新数据库,若要手动讄事务相关操作Q你可以重蝲onSetUpInTransaction?nbsp;onTearDownInTransactionҎ(gu)Q以便手工开始ƈ提交事务Q或者调用setComplete()Ҏ(gu)。这个类也可以在没有事务的情况下Q用这个类?br />    </span><span style="color: #000000;">4</span><span style="color: #000000;">. AbstractTransactionalDataSourceSpringContextTestsQ这?nbsp;AbstractTransactionalSpringContextTests的直接子c,它用了Spring的基于JDBC?nbsp;jdbcTemplate工具c,支持数据库别的事务?br /> <br /> 二、如何在你的TestCase Class里取得spring context<br /> <br />      你的TestCase Class必须l承的是上述四个AbstractXXXSpringContextTests中的其中一个,那么必dC面这个方法来取得spring contextQ?br /> <br />       </span><span style="color: #0000ff;">protected</span><span style="color: #000000;"> </span><span style="color: #0000ff;">abstract</span><span style="color: #000000;"> String[] getConfigLocations();<br /> <br />       例如Q?br /> <br />       </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String[] getConfigLocations() {<br />            String[] configLocations </span><span style="color: #000000;">=</span><span style="color: #000000;"> { </span><span style="color: #000000;">"</span><span style="color: #000000;">applicationContext.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">hibernate-context.xml</span><span style="color: #000000;">"</span><span style="color: #000000;"> };<br />            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> configLocations;<br />        }<br /> <br /> <br /> ?nbsp;注意要加载的context xml file的\径问题:(x)上述的代码是ZclasspathQ因此applicationContext.xml和hibernate</span><span style="color: #000000;">-</span><span style="color: #000000;"> context.xml必须攑֜classpath里(Ҏ(gu)一是把xml files攑ֈWEB</span><span style="color: #000000;">-</span><span style="color: #000000;">INF</span><span style="color: #000000;">/</span><span style="color: #000000;">classes目录下,另一U方法就是在project properties里把xml files的\径加到classpath里)<br /> <br /> 那么如果你一定要把context xml files攑ֈWEB</span><span style="color: #000000;">-</span><span style="color: #000000;">INF目录下,也是可以的,那么应该Zfile(Zfile的相对\径是相对于project root folder)Q代码如下:(x)<br /> <br />  </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String[] getConfigLocations() {<br />     String[] configLocations </span><span style="color: #000000;">=</span><span style="color: #000000;"> { </span><span style="color: #000000;">"</span><span style="color: #000000;">file:WebContent/WEB-INF/applicationContext.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">};<br />     </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> configLocations;<br />  }<br /> <br /> AbstractXXXSpringContextTests׃(x)Ҏ(gu)Ҏ(gu)getConfigLocationsҎ(gu)q回的context xml位置的数l来加蝲q且对加载的Context提供~存。这是非帔R要的Q因为如果你在从事一个大目Ӟ启动旉可能成ؓ(f)一个问题-Q这不是 Spring自n的开销Q而是被Spring容器实例化的对象在实?nbsp;化自w时所需要的旉。例如,一个包?0</span><span style="color: #000000;">-</span><span style="color: #000000;">100个Hibernate映射文g的项目可能需?0</span><span style="color: #000000;">-</span><span style="color: #000000;">20U的旉来加载上q的映射文gQ如果在q行每个试fixture里的每个试案例前都有这L(fng)开销Q将D整个试工作的gӞ最l有可能Q实际上很可能)降低效率?br /> <br /> 在某U极偶然的情况下Q某个测试可?#8220;弄脏”了配|场所Qƈ要求重新加蝲Q-例如改变一个bean的定义或者一个应用对象的状态-Q你可以调用 AbstractDependencyInjectionSpringContextTests 上的 setDirty() Ҏ(gu)来重新加载配|ƈ在执行下一个测试案例前重徏application context<br /> <br />  <br /> <br /> 当类 AbstractDependencyInjectionSpringContextTestsQ及(qing)其子c)装蝲你的Application ContextӞ你可以通过SetterҎ(gu)来注入你惌的来自context的bean,而不需要显式的调用 applicationContext.getBean(XXX)。因?nbsp;AbstractDependencyInjectionSpringContextTests?x)从getConfigLocations()Ҏ(gu)指定的配|文件中帮你自动注入<br /> <br /> 下面的例子就是通过setterҎ(gu)来获得context里的ProductManager beanQ?br /> <br /> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> MyTest </span><span style="color: #0000ff;">extends</span><span style="color: #000000;"> AbstractDependencyInjectionSpringContextTests {<br />     ProductManager productManager;<br /> <br />     </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String[] getConfigLocations() {<br />         String[] configLocations </span><span style="color: #000000;">=</span><span style="color: #000000;"> { </span><span style="color: #000000;">"</span><span style="color: #000000;">file:WebContent/WEB-INF/applicationContext.xml</span><span style="color: #000000;">"</span><span style="color: #000000;"> };<br />         </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> configLocations;<br />     }<br /> <br />     </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> testGetProduct() {<br />        assertEquals(</span><span style="color: #000000;">"</span><span style="color: #000000;">tomson</span><span style="color: #000000;">"</span><span style="color: #000000;">,productManager.getProductByName(</span><span style="color: #000000;">"</span><span style="color: #000000;">tomson</span><span style="color: #000000;">"</span><span style="color: #000000;">).getName());<br />     }<br />    <br /> <br />     </span><span style="color: #008000;">//</span><span style="color: #008000;">通过setterҎ(gu)自动从context里注入productManager beanQ而不用显C用applicationContext.getBean(XXX)</span><span style="color: #008000;"><br /> </span><span style="color: #000000;">    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> setProductManager(ProductManager productManager) {<br />        </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.productManager </span><span style="color: #000000;">=</span><span style="color: #000000;"> productManager;<br />     }<br /> }<br /> 但是?nbsp;果context里有多个bean都定义ؓ(f)一个类型(例如有多个bean都是ProductManager classcd的)Q那么对q些bean无法通过setterҎ(gu)来自动依赖注入(因ؓ(f)有多个bean同一个类型,不知要自动注入哪个)。在q种情况?nbsp;你需要显C的调用applicationContext.getBean(XXX)来注入。如Q?br /> <br /> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> MyTest </span><span style="color: #0000ff;">extends</span><span style="color: #000000;"> AbstractDependencyInjectionSpringContextTests {<br />    ProductManager productManager;<br /> <br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String[] getConfigLocations() {<br />       String[] configLocations </span><span style="color: #000000;">=</span><span style="color: #000000;"> { </span><span style="color: #000000;">"</span><span style="color: #000000;">file:WebContent/WEB-INF/applicationContext.xml</span><span style="color: #000000;">"</span><span style="color: #000000;"> };<br />       </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> configLocations;<br />    }<br /> <br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> onSetUp() {<br />        productManager </span><span style="color: #000000;">=</span><span style="color: #000000;"> (ProductManager) applicationContext.getBean(</span><span style="color: #000000;">"</span><span style="color: #000000;">productManager</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />    }<br /> <br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> testGetProduct() {<br />        assertEquals(</span><span style="color: #000000;">"</span><span style="color: #000000;">tomson</span><span style="color: #000000;">"</span><span style="color: #000000;">,productManager.getProductByName(</span><span style="color: #000000;">"</span><span style="color: #000000;">tomson</span><span style="color: #000000;">"</span><span style="color: #000000;">).getName());<br />    }<br />  <br /> }<br /> <br /> 如果你的TestCase不用依赖注入,只要不定义Q何settersҎ(gu)卛_。或者你可以l承 AbstractSpringContextTests Q-q个 org.springframework.test 包中的根c,而不是承AbstractDependencyInjectionSpringContextTestsQ及(qing)其子c)。这是因?nbsp;AbstractSpringContextTests 只包括用来加载Spring Context的便利方法但没有自动依赖注入的功能?br /> <br /> </span></div> <img src ="http://m.tkk7.com/ashutc/aggbug/331175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2010-09-06 11:02 <a href="http://m.tkk7.com/ashutc/archive/2010/09/06/331175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unable to load configuration. - bean - jar:file:/D:/Tomcat-6.0.18/webapps/teabank/WEB-INF/lib/struts2-core-2.1.6.jar!/struts-default.xmlhttp://m.tkk7.com/ashutc/archive/2010/07/09/325671.html西瓜西瓜Fri, 09 Jul 2010 08:45:00 GMThttp://m.tkk7.com/ashutc/archive/2010/07/09/325671.htmlhttp://m.tkk7.com/ashutc/comments/325671.htmlhttp://m.tkk7.com/ashutc/archive/2010/07/09/325671.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/325671.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/325671.htmlStruts2所需的jar包导入不全,D该错误?/span>

主要需要以下几个jar包:(x)


struts2-core-2.1.6.jar
xwork-2.1.2.jar
ognl-2.6.11.jar
freemarker-2.3.13.jar
commons-logging.jar
commons-fileupload.jar
commons-io.jar


西瓜 2010-07-09 16:45 发表评论
]]>
struts2 文g上传?qing)羃?/title><link>http://m.tkk7.com/ashutc/archive/2010/06/03/322682.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Thu, 03 Jun 2010 14:54:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2010/06/03/322682.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/322682.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2010/06/03/322682.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/322682.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/322682.html</trackback:ping><description><![CDATA[     摘要: Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->package upload; import java.io.*; import java.util.*; import com.sun.im...  <a href='http://m.tkk7.com/ashutc/archive/2010/06/03/322682.html'>阅读全文</a><img src ="http://m.tkk7.com/ashutc/aggbug/322682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2010-06-03 22:54 <a href="http://m.tkk7.com/ashutc/archive/2010/06/03/322682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>userloginhttp://m.tkk7.com/ashutc/archive/2010/04/06/317590.html西瓜西瓜Tue, 06 Apr 2010 13:42:00 GMThttp://m.tkk7.com/ashutc/archive/2010/04/06/317590.htmlhttp://m.tkk7.com/ashutc/comments/317590.htmlhttp://m.tkk7.com/ashutc/archive/2010/04/06/317590.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/317590.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/317590.html阅读全文

西瓜 2010-04-06 21:42 发表评论
]]>
Hibernateq发控制乐观锁实现——Versionhttp://m.tkk7.com/ashutc/archive/2010/01/22/310557.html西瓜西瓜Fri, 22 Jan 2010 12:09:00 GMThttp://m.tkk7.com/ashutc/archive/2010/01/22/310557.htmlhttp://m.tkk7.com/ashutc/comments/310557.htmlhttp://m.tkk7.com/ashutc/archive/2010/01/22/310557.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/310557.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/310557.html乐观q发控制Q可以有三种方式?/p>

1QVersion版本?/p>

2Q时间戳

3Q自动版本控制?/p>

q里不徏议在新的应用E序中定义没有版本或者时间戳列的版本控制Q它更慢Q更复杂Q如果你正在使用q对象Q它则不?x)生效?/p>

以下信息来自 : http://esffor.javaeye.com/blog/168243

通过在表中及(qing)POJO中增加一个version字段来表C录的版本Q来辑ֈ多用户同时更改一条数据的冲突

数据库脚本:(x) 

create table studentVersion (id varchar(32),name varchar(32),ver int);

POJO

package Version;

public class Student {
  
private String id;
  
private String name;
  
private int version;
public String getId() {
    
return id;
}

public void setId(String id) {
    
this.id = id;
}

public String getName() {
    
return name;
}

public void setName(String name) {
    
this.name = name;
}

public int getVersion() {
    
return version;
}

public void setVersion(int version) {
    
this.version = version;
}



}

Student.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
<!-- 
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="Version.Student" table="studentVersion" >
    
<id name="id" unsaved-value="null">
      
<generator class="uuid.hex"></generator>
    
</id>
    
<!--version标签必须跟在id标签后面-->
    
<version name="version" column="ver" type="int"></version>
    
<property name="name" type="string" column="name"></property>  
</class>

</hibernate-mapping>

Hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
>

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
    
<property name="connection.username">root</property>
    
<property name="connection.url">
        jdbc:mysql://localhost:3306/schoolproject?characterEncoding=gb2312
&amp;useUnicode=true
    
</property>
    
<property name="dialect">
        org.hibernate.dialect.MySQLDialect
    
</property>
    
<property name="myeclipse.connection.profile">mysql</property>
    
<property name="connection.password">1234</property>
    
<property name="connection.driver_class">
        com.mysql.jdbc.Driver
    
</property>
    
<property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    
</property>
    
<property name="hibernate.show_sql">true</property>
    
<property name="current_session_context_class">thread</property>
    
<property name="jdbc.batch_size">15</property>
    
<mapping resource="Version/Student.hbm.xml" />




</session-factory>

</hibernate-configuration>

试代码Q?/p>

package Version;


import java.io.File;
import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {


    
public static void main(String[] args) {

        String filePath
=System.getProperty("user.dir")+File.separator+"src/Version"+File.separator+"hibernate.cfg.xml";
        File file
=new File(filePath);
        System.out.println(filePath);
        SessionFactory sessionFactory
=new Configuration().configure(file).buildSessionFactory();
        Session session
=sessionFactory.openSession();
        Transaction t
=session.beginTransaction();
        
        Student stu
=new Student();
        stu.setName(
"tom11");
        session.save(stu);
        t.commit();
      
        
        
/*
         * 模拟多个session操作student数据?br />          
*/

        
        Session session1
=sessionFactory.openSession();
        Session session2
=sessionFactory.openSession();
        Student stu1
=(Student)session1.createQuery("from Student s where s.name='tom11'").uniqueResult();
        Student stu2
=(Student)session2.createQuery("from Student s where s.name='tom11'").uniqueResult();
        
        
//q时候,两个版本h相同?/span>
        System.out.println("v1="+stu1.getVersion()+"--v2="+stu2.getVersion());
        
        Transaction tx1
=session1.beginTransaction();
        stu1.setName(
"session1");
        tx1.commit();
        
//q时候,两个版本h不同的,其中一个的版本号递增?/span>
        System.out.println("v1="+stu1.getVersion()+"--v2="+stu2.getVersion());
        
        Transaction tx2
=session2.beginTransaction();
        stu2.setName(
"session2");
        tx2.commit();
        
        
        
    }


}

q行l果Q?/p>

Hibernate: insert into studentVersion (ver, name, id) values (?, ?, ?)
Hibernate: select student0_.id as id0_, student0_.ver as ver0_, student0_.name as name0_ from studentVersion student0_ where student0_.name='tom11'
Hibernate: select student0_.id as id0_, student0_.ver as ver0_, student0_.name as name0_ from studentVersion student0_ where student0_.name='tom11'
v1=0--v2=0
Hibernate: update studentVersion set ver=?, name=? where id=? and ver=?
v1=1--v2=0
Hibernate: update studentVersion set ver=?, name=? where id=? and ver=?
Exception in thread "main" org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Version.Student#4028818316cd6b460116cd6b50830001]

可以看到Q第二个“用户”session2修改数据时候,记录的版本号已经被session1更新q了Q所以抛ZU色的异常,我们可以在实际应? 中处理这个异常,例如在处理中重新d数据库中的数据,同时目前的数据与数据库中的数据展示出来Q让使用者有Z(x)比较一下,或者设计程序自动读取新的数 ?/p>

注意Q?/strong>

    要注意的是,׃乐观锁定是用系l中的程式来控制Q而不是用资料库中的锁定机制Q因而如果有人特意自行更新版本讯息来过(g)查,则锁定机制就?x)无效,例如在上例中自行更?span style="color: #ff0000;">stu的version属性,使之与资料库中的版本L(fng)同的话就不会(x)有错误,像这L(fng)本号被更改,或是׃资料是由外部pȝ而来Q因而版本资讯不受控制时Q锁定机制将?x)有问题Q设计时必须注意?/span>

    如果手工讄stu.setVersion()自行更新版本以蟩q检?则这U乐观锁׃(x)失效Q应Ҏ(gu)法可以将Student.java的setVersion讄成private



西瓜 2010-01-22 20:09 发表评论
]]>
struts2验证框架http://m.tkk7.com/ashutc/archive/2009/11/11/302023.html西瓜西瓜Wed, 11 Nov 2009 14:35:00 GMThttp://m.tkk7.com/ashutc/archive/2009/11/11/302023.htmlhttp://m.tkk7.com/ashutc/comments/302023.htmlhttp://m.tkk7.com/ashutc/archive/2009/11/11/302023.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/302023.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/302023.html                      <action name="saveUser" class="saveUserAction" method="save">
                       <result name="success" type="redirect">listUser!list.action</result>
                       <result name="input">/save.jsp</result>
                     </action>

saveUserAction 里面有方?br />                                      public String save() throws Exception {
                                              this.service.saveUser(user);
                                     return SUCCESS;
                                                }

然后我们验证文g配置成UserAction-save-validation.xml。这样struts验证是不?x)成功的?br /> 因ؓ(f)验证跟本pmethod指定的方法和action里面的方法名无关Q而是和struts.xml里面的name指定的名字有养I
如果我们的配|文件这样命名:(x)UserAction-aveUser-validation.xml 那么才能验证成功

UserAction-aveUser-validation.xml Q?br /> <validators>
 <field name="user.age">
  <field-validator type="required">
   <message>required age</message>
  </field-validator>
  <field-validator type="int">
   <param name="min">1</param>
   <param name="max">150</param>
   <message>age should be between ${min} and ${max}</message>
  </field-validator>
 </field>
</validators>

防止验证出现多行重复性提C?scope定义为prototype使struts2的action不用单例模?br />     <bean id="saveUserAction" class="com.yu.useraction.saveUserAction" scope="prototype">
        <property name="service" ref="userService"></property>
    </bean>
所有在spring里面的action都需要配|scope="prototype"不能使用默认


如果oracle数据?把age的Longcd都改成IntergercdQuser.java和user.hbm.xmlQ,否者验证时?x)不能通过


西瓜 2009-11-11 22:35 发表评论
]]>
Caught exception while loading file struts-default.xml 错误http://m.tkk7.com/ashutc/archive/2009/11/11/302011.html西瓜西瓜Wed, 11 Nov 2009 12:56:00 GMThttp://m.tkk7.com/ashutc/archive/2009/11/11/302011.htmlhttp://m.tkk7.com/ashutc/comments/302011.htmlhttp://m.tkk7.com/ashutc/archive/2009/11/11/302011.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/302011.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/302011.html严重: Exception starting filter struts2

Caught exception while loading file struts-default.xml - [unknown location]

at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadConfigurationFiles(XmlConfigurationProvider.java:839)

at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadDocuments(XmlConfigurationProvider.java:131)

at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.init(XmlConfigurationProvider.java:100)

……………………………………

现象: W一ơ能q行, reload׃?

试了Struts2自带的blank? 没问?

那基本可断定是其他jar包有冲突, 应该是XML解析包有冲突.

(g)查发布后的WEB-INF/lib有两个XML解析? xml-apis.jar和xerces-2.6.2.jar

q种错误真正原因不是JDK 6和Struts 2冲突, 而是 MyEclipse Hibernate cd中多了两个包: xml-apis.jar和xerces-2.6.2.jar, q两个包的功能和JDK的冲H了. 解决办法: 1. 删除发布后目录的 WEB-INF/lib/ 下的q两个文? 2. 或者用JDK 1.5来启动Tomcat 6.



西瓜 2009-11-11 20:56 发表评论
]]>
Hibernate二~存ehcache配置http://m.tkk7.com/ashutc/archive/2009/10/31/300486.html西瓜西瓜Sat, 31 Oct 2009 07:45:00 GMThttp://m.tkk7.com/ashutc/archive/2009/10/31/300486.htmlhttp://m.tkk7.com/ashutc/comments/300486.htmlhttp://m.tkk7.com/ashutc/archive/2009/10/31/300486.html#Feedback2http://m.tkk7.com/ashutc/comments/commentRss/300486.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/300486.html需要两个包:
commons-logging-1.0.4.jar
ehcache-1.2.3.jar

在src根目录下新徏 ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
 
<diskStore path="java.io.tmpdir" />
 
<defaultCache maxElementsInMemory="10000" eternal="false"
  timeToIdleSeconds
="120" timeToLiveSeconds="120" overflowToDisk="true"
  diskExpiryThreadIntervalSeconds
="120" memoryStoreEvictionPolicy="LRU" />
 
<cache name="cn.yu.vo.Guestbook" maxElementsInMemory="1000" eternal="false"
  timeToIdleSeconds
="3000" timeToLiveSeconds="600" overflowToDisk="true"/>
</ehcache>
  <!-- 
          diskStore:保存在硬盘上的(f)时目?br />           
          nameQCache的唯一标识

          maxElementsInMemoryQ内存中最大缓存对象数?br />
          maxElementsOnDiskQ磁盘中最大缓存对象数Q若?表示无穷大?br />
          eternalQElement是否怹有效Q一但设|了Qtimeout不起作用?br />
          overflowToDiskQ配|此属性,当内存中Element数量辑ֈmaxElementsInMemoryӞEhcache会(x)Element写到盘中?br />
          timeToIdleSecondsQ设|Element在失效前的允?dng)R|时间。仅当element不是怹有效时用,可选属性,默认值是0Q?nbsp;
                                              也就是可闲置旉无穷大?br />
          timeToLiveSecondsQ设|Element在失效前允许存活旉。最大时间介于创建时间和失效旉之间。仅当element不是怹
                                              有效时用,默认?.Q?nbsp; 也就是element存活旉无穷大?br />
          diskPersistentQ是否缓存虚拟机重启期数据。(q个虚拟机是指什么虚拟机一直没看明白是什?有高希望能指?br />                                        一二)?br />
          diskExpiryThreadIntervalSecondsQ磁盘失效线E运行时间间隔,默认?20U?br />
          diskSpoolBufferSizeMBQ这个参数设|DiskStoreQ磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一
                                                     个缓冲区?br />
          memoryStoreEvictionPolicyQ当辑ֈmaxElementsInMemory限制ӞEhcache会(x)Ҏ(gu)指定的策略去清理内存。默认策略是
                                                           LRUQ最q最用)。你可以讄为FIFOQ先q先出)或是LFUQ较?yu)用)。这里比?br />                                                            遗憾QEhcacheq没有提供一个用户定制策略的接口Q仅仅支持三U指定策略,感觉做的不够
                                                           理想?br />  
-->

在hibernate.cfg.xml里面新增属?br />
    <property name="cache.provider_class">
        org.hibernate.cache.EhCacheProvider
    
</property>
在guestbook.hbm.xml里面新增属?br />
    <class name="cn.yu.vo.Guestbook" table="GUESTBOOK" schema="OLIVER">
    
<cache usage="read-write"/>
        
<id name="id" type="java.lang.Long">
            
<column name="ID" precision="22" scale="0" />
            
<generator class="sequence">
             
<param name="sequence">gb_seq</param>
             
</generator>
        
</id>


西瓜 2009-10-31 15:45 发表评论
]]>
Hibernate3.0 HQL条g子语句like 中文qhttp://m.tkk7.com/ashutc/archive/2009/10/31/300439.html西瓜西瓜Fri, 30 Oct 2009 20:09:00 GMThttp://m.tkk7.com/ashutc/archive/2009/10/31/300439.htmlhttp://m.tkk7.com/ashutc/comments/300439.htmlhttp://m.tkk7.com/ashutc/archive/2009/10/31/300439.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/300439.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/300439.html String hql = "FROM Table AS t WHERE t.field like '%" + str + "%'";

Query query = getSession().createQuery(hql);
query.list();

使用q种形式传入参数str, ?x)导致控制台输?
FROM Table AS t WHERE t.field like '% ????%'
之类的ؕ? 从而在数据库找不到匚w记录.

据说q是hibernate3.0 like子句处理中文的一个问? 3.1已得C正?.0版可以通过讄参数解决。改正如下:(x)

String str = "中文字符?;
String hql = "FROM Table AS t WHERE t.field LIKE :param";
Query query = getSession().createQuery(hql);
query.setString("param", "%" + str + "%");
query.list();


西瓜 2009-10-31 04:09 发表评论
]]>
getCurrentSession ?openSession() 的区?http://m.tkk7.com/ashutc/archive/2009/09/27/296632.html西瓜西瓜Sun, 27 Sep 2009 05:50:00 GMThttp://m.tkk7.com/ashutc/archive/2009/09/27/296632.htmlhttp://m.tkk7.com/ashutc/comments/296632.htmlhttp://m.tkk7.com/ashutc/archive/2009/09/27/296632.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/296632.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/296632.html  getCurrentSession创徏的session?x)和l定到当前线E?而openSession不会(x)?/font>

  getCurrentSession创徏的线E会(x)在事务回滚或事物提交后自动关?而openSession必须手动关闭

         q里getCurrentSession本地事务(本地事务:jdbc)?要在配置文g里进行如下设|?/font>

         如果使用的是本地事务Qjdbc事务Q?br />             <property name="hibernate.current_session_context_class">thread</property>
         如果使用的是全局事务Qjta事务Q?br />             <property name="hibernate.current_session_context_class">jta</property> 

   getCurrentSession ()使用当前的sessionQopenSession()重新建立一个新的session

   在一个应用程序中Q如果DAO 层用Spring 的hibernate 模板Q通过Spring 来控制session 的生命周期,则首选getCurrentSession ()?/font>

   使用Hibernate的大多数应用E序需要某UŞ式的“上下文相关的” sessionQ特定的session在整个特定的上下文范围内始终有效。然而,对不同类型的应用E序而言Q要Z么是l成q种“上下?#8221;下一个定义通常 是困隄Q不同的上下文对“当前”q个概念定义了不同的范围。在3.0版本之前Q用Hibernate的程序要么采用自行编写的Z ThreadLocal的上下文sessionQ要么采用HibernateUtilq样的辅助类Q要么采用第三方框架Q比如Spring或Pico)Q?它们提供了基于代?proxy)或者基于拦截器(interception)的上下文相关session?

   ?.0.1版本开 始,Hibernate增加了SessionFactory.getCurrentSession()Ҏ(gu)。一开始,它假定了采用JTA事务QJTA事务 定义了当前session的范围和上下?scope and context)。Hibernate开发团队坚信,因ؓ(f)有好几个独立的JTA TransactionManager实现E_可用Q不论是否被部vC个J2EE容器中,大多?假若不是所有的Q应用程序都应该采用JTA事务理?Zq一点,采用JTA的上下文相关session可以满你一切需要?

   更好的是Q从3.1开 始,SessionFactory.getCurrentSession()的后台实现是可拔插的。因此,我们引入了新的扩展接?(org.hibernate.context.CurrentSessionContext)和新的配|参?(hibernate.current_session_context_class)Q以便对什么是“当前session”的范围和上下?scope and context)的定义进行拔插?

   请参?org.hibernate.context.CurrentSessionContext接口的Javadoc,那里有关于它的契U的详细讨论。它定义 了单一的方法,currentSession()Q特定的实现用它来负责跟t当前的上下文session。Hibernate内置了此接口的两U实现?

   org.hibernate.context.JTASessionContext - 当前sessionҎ(gu)JTA来跟t和界定。这和以前的仅支持JTA的方法是完全一L(fng)。详情请参阅Javadoc?

   org.hibernate.context.ThreadLocalSessionContext - 当前session通过当前执行的线E来跟踪和界定。详情也请参阅Javadoc?

   q两U实现都提供?#8220;每数据库事务对应一个session”的编E模型,也称作每ơ请求一个session。Hibernate session的v始和l结由数据库事务的生存来控制。假若你采用自行~写代码来管理事务(比如Q在Ua(b)的J2SE,或?JTA/UserTransaction/BMTQ,你用Hibernate Transaction API来把底层事务实现从你的代码中隐藏掉。如果你在支持CMT的EJB容器中执行,事务边界是声明式定义的,你不需要在代码中进行Q何事务或 session理操作。请参阅W?11 ?事务和ƈ发一节来阅读更多的内容和CZ代码?

   hibernate.current_session_context_class 配置参数定义了应该采用哪?nbsp;         

   org.hibernate.context.CurrentSessionContext实现。注意,Z向下兼容Q如果未 配置此参敎ͼ但是存在 

   org.hibernate.transaction.TransactionManagerLookup的配 |,Hibernate?x)采?nbsp;

   org.hibernate.context.JTASessionContext。一般而言Q此参数的值指明了要用的?现类的全名,但那两个内置的实现可以用简写,?jta"?thread"?/font>


                                利于ThreadLocal模式理Session
   早在Java1.2推出之时QJavaq_中就引入了一个新的支持:(x)java.lang.ThreadLocalQ给我们在编写多U程E序
   时提供了一U新的选择。ThreadLocal是什么呢Q其实ThreadLocalq是一个线E的本地实现版本Q它q不是一个ThreadQ?br />    而是thread local variable(U程局部变?。也许把它命名ؓ(f)ThreadLocalVar更加合适。线E局部变?ThreadLocal)
   其实的功用非常简单,是为每一个用某变量的线E都提供一个该变量值的副本Q是每一个线E都可以独立地改变自q副本Q?br />    而不?x)和其它U程的副本冲H。从U程的角度看Q就好像每一个线E都完全拥有一个该变量?
   ThreadLocal是如何做Cؓ(f)每一个线E维护变量的副本的呢Q其实实现的思\很简单,在ThreadLocalcM有一个MapQ?br />    用于存储每一个线E的变量的副本。比如下面的CZ实现(Z单,没有考虑集合的泛?Q?
public class HibernateUtil {

public static final ThreadLocal session =new ThreadLocal();

public static final SessionFactory sessionFactory;
   static {
      try {
        sessionFactory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) {
           throw new ExceptionInInitializerError(ex);
      }    
}

     public static Session currentSession() throws HibernateException {
        Session s = session.get();
        if(s == null) {
          s = sessionFactory.openSession();
          session.set(s);
           }
         return s;
       }

    public static void closeSession() throws HibernateException {
           Session s = session.get();
        if(s != null) {
            s.close();
        }
        session.set(null);
    }
}

openSession() ?getCurrentSession() 有何不同和关联呢Q?

 

   ?SessionFactory 启动的时候, Hibernate ?x)根据配|创建相应的 CurrentSessionContext Q在 getCurrentSession() 被调用的时候,实际被执行的Ҏ(gu)?CurrentSessionContext.currentSession() 。在 currentSession() 执行Ӟ如果当前 Session 为空Q?currentSession ?x)调?SessionFactory ?openSession 。所?getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法?/font>


本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/LoveYouT/archive/2009/05/17/4193894.aspx



西瓜 2009-09-27 13:50 发表评论
]]>
Struts1和Struts2的区别和Ҏ(gu)http://m.tkk7.com/ashutc/archive/2009/06/19/283206.html西瓜西瓜Fri, 19 Jun 2009 04:32:00 GMThttp://m.tkk7.com/ashutc/archive/2009/06/19/283206.htmlhttp://m.tkk7.com/ashutc/comments/283206.htmlhttp://m.tkk7.com/ashutc/archive/2009/06/19/283206.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/283206.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/283206.html • Struts1要求Actioncȝ承一个抽象基cRStruts1的一个普遍问题是使用抽象cȝE而不是接口?
• Struts 2 Actioncd以实C个Action接口Q也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类?实现 常用的接口。Action接口不是必须的,M有execute标识的POJO对象都可以用作Struts2的Action对象?

U程模式:
• Struts1 Action是单例模式ƈ且必LU程安全的,因ؓ(f)仅有Action的一个实例来处理所有的h。单例策略限制了Struts1 Action能作的事Qƈ且要在开发时特别心。Action资源必须是线E安全的或同步的?
• Struts2 Action对象为每一个请求生一个实例,因此没有U程安全问题。(实际上,servlet容器l每个请求生许多可丢弃的对象,q且不会(x)D性能和垃圑֛攉题)

Servlet 依赖:
• Struts1 Action 依赖于Servlet API ,因ؓ(f)当一个Action被调用时HttpServletRequest ?HttpServletResponse 被传递给executeҎ(gu)?
• Struts 2 Action不依赖于容器Q允许Actionq容器单独被测试。如果需要,Struts2 Action仍然可以讉K初始的request和response。但是,其他的元素减或者消除了直接讉KHttpServetRequest ?HttpServletResponse的必要性?

可测?
• 试Struts1 Action的一个主要问题是executeҎ(gu)暴露了servlet APIQ这使得试要依赖于容器Q。一个第三方扩展Q-Struts TestCaseQ-提供了一套Struts1的模拟对象(来进行测试)?
• Struts 2 Action可以通过初始化、设|属性、调用方法来试Q?#8220;依赖注入”支持也ɋ试更容易?

捕获输入:
• Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须l承一个基cR因为其他JavaBean不能用作ActionFormQ开发者经 常创建多余的cL莯入。动态BeanQDynaBeansQ可以作为创ZlActionForm的选择Q但是,开发者可能是在重新描q?创徏)已经?在的JavaBeanQ仍然会(x)D有冗余的javabeanQ?
• Struts 2直接使用Action属性作入属性,消除了对W二个输入对象的需求。输入属性可能是有自??属性的rich对象cd。Action属性能够通过 web面上的taglibs讉K。Struts2也支持ActionForm模式。rich对象cdQ包括业务对象,能够用作输入/输出对象。这U?ModelDriven Ҏ(gu)简化了taglib对POJO输入对象的引用?

表达式语aQ?
• Struts1 整合了JSTLQ因此用JSTL EL。这UEL有基本对象图遍历Q但是对集合和烦引属性的支持很弱?
• Struts2可以使用JSTLQ但是也支持一个更强大和灵zȝ表达式语aQ-"Object Graph Notation Language" (OGNL).

l定值到面QviewQ?
• Struts 1使用标准JSP机制把对象绑定到面中来讉K?
• Struts 2 使用 "ValueStack"技术,使taglib能够讉KD不需要把你的面QviewQ和对象l定h。ValueStack{略允许通过一pd名称相同但类型不同的属性重用页面(viewQ?

cd转换Q?
• Struts 1 ActionForm 属性通常都是Stringcd。Struts1使用Commons-Beanutilsq行cd转换。每个类一个{换器Q对每一个实例来说是不可配置的?
• Struts2 使用OGNLq行cd转换。提供基本和常用对象的{换器?

校验Q?
• Struts 1支持在ActionForm的validateҎ(gu)中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容Q但不能校验子对象?
• Struts2支持通过validateҎ(gu)和XWork校验框架来进行校验。XWork校验框架使用为属性类cd定义的校验和内容校验Q来支持chain校验子属?

Action执行的控Ӟ(x)
• Struts1支持每一个模块有单独的Request ProcessorsQ生命周期)Q但是模块中的所有Action必须׃n相同的生命周期?
• Struts2支持通过拦截器堆栈(Interceptor StacksQؓ(f)每一个Action创徏不同的生命周期。堆栈能够根据需要和不同的Action一起用?

西瓜 2009-06-19 12:32 发表评论
]]>
struts 四种验证Ҏ(gu)http://m.tkk7.com/ashutc/archive/2009/06/09/280997.html西瓜西瓜Tue, 09 Jun 2009 10:51:00 GMThttp://m.tkk7.com/ashutc/archive/2009/06/09/280997.htmlhttp://m.tkk7.com/ashutc/comments/280997.htmlhttp://m.tkk7.com/ashutc/archive/2009/06/09/280997.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/280997.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/280997.html


文gstruts-config.xml :

<action-mappings>
  <action attribute="userloginForm" input="/login.jsp"
   name="userloginForm" parameter="method" path="/userlogin"
   scope="request" validate="true"
   type="cn.userlogin.struts.action.UserloginAction" />

 </action-mappings>
 <message-resources
  parameter="cn.userlogin.struts.ApplicationResources" />
 <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
  <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
 </plug-in>


1Q用Javascript在客L(fng)q行验证
配置Q在需要验证的JSP文g中写?/font>

<html:form action="/XXX" onsubmit="return validateXXXX(this);">
q里的XXX 是与要进行验证的 forward name
validateXXXX (this);里面的XXXX是需要进行验证的ActionForm?/font>

<html:javascript formName="mytestForm"/>

在validation.xml文g中写入验证代码就可以q行基本的验证了。具体请参照http://www.chinajavaworld.net/forum/topic.cgi?forum=48&topic=1413&show=50

 

q种Ҏ(gu)是在客户端进行验证,客户端可以看到JAVASCRIPT部分的全代码。安全性不?/font>

 


2Q自己的ActionForml承ValidatorFormc,在里面编写自qҎ(gu)Q?br /> public ActionErrors validate (ActionMapping mapping,HttpServletRequest request) {


        ActionErrors errors = new ActionErrors();


。。。。。?br /> if ( mytext.equals("aaa") ) {                    //my example
       errors.add("mytext",new ActionError("mytext.error"));
}
。。。。。?br /> return errors;


}
此时Q如果写了这个方法,׃(x)屏蔽掉在Validation.xml中定义的验证部分Q换句话说就是系l运行时QValidation.xml里对应此ActionForm的定义的错误验证部分不实?br /> 如果不写q个Ҏ(gu)的话Q系l运行时?x)进行Validation.xml里对应此ActionForm的定义的错误验证部分的操?/font>

此类Ҏ(gu)是在服务器端q行验证Q验证部分代码客L(fng)不可见?/font>

 


3Q动态验证DynaValidatorForm的?br />   不需要再写对应的ActionFormQ只需在struts-config.xml里把自己的ActionFormq行配置

    <form-bean      name="testForm"
        type="org.apache.struts.validator.DynaValidatorForm">
       <form-property name="mytext" type="java.lang.String"/>
       <form-property name="mytextarea" type="java.lang.String"/>
       <form-property name="mydatetext" type="java.lang.String"/>
    </form-bean>

在form-property里设|相应的目Q比如说mytextQmytextarea什么的Q执行的时候会(x)动态生成ActionForm

   再在validation.xml里写入所希望的验证代码,可以了


JSP文g里不需要写入Q何东西,验证也是在服务器端进行,验证部分代码在JSP中不可见


 


4Q组合验?br /> 如果使用动态验证DynaValidatorForm的话Q不许编写自q对应的ActionFormQ相应的Ҏ(gu)验证?x)受到相当程度的限制?/font>


q个时候,需要将Ҏ(gu)验证部分写入对应的ActionQ?/font>


if(mytext.equals("aaa")){                    //My Example
ActionErrors errors = new ActionErrors();
errors.add("***",new ActionError("***.error"));      
saveErrors(request,errors);return (mapping.findForward("false"));
}


 



西瓜 2009-06-09 18:51 发表评论
]]>struts2 mvc视图实例分析http://m.tkk7.com/ashutc/archive/2009/05/29/278955.html西瓜西瓜Fri, 29 May 2009 14:41:00 GMThttp://m.tkk7.com/ashutc/archive/2009/05/29/278955.htmlhttp://m.tkk7.com/ashutc/comments/278955.htmlhttp://m.tkk7.com/ashutc/archive/2009/05/29/278955.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/278955.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/278955.html从一个高度层ơ来?Strtsu2属性pull-MVC(或是MVC2)框架;q与传统的MVC框架略有不同,因ؓ(f)action的角色采用模?而不是控制器,虽然q样有一些重?"pull"来自于视图从action拉数?而不是持有一个分开的可用模型对?

我们知道在概忉|面意味着什?但在执行层面意味着什?q个模型-视图-控制器模式在Struts2中被实现成了五个核心部分--actions,拦截?值栈/OGNL,l果cd和结?视图技?

?:The MVC / Struts2 Architecture

?描述了从Struts2高度层面上的l构, 包含了模?视图和控制器.控制器是一个实CStruts2里分zServletqo(h)器以?qing)拦截?模型实现的actions,视图则是q果类型和l果的组?值栈和ONGL提供了一个通用的\U,链接和集成其他组?

我们在这章讨Z些通用的部?会(x)有很多信息涉?qing)到配?配置WEB应用,配置a(chn)ctions,拦截?l果{等.C,q些说明只是Z提供如果完成的背?或许不是最有效的配|应用的方式.在后面的章节我们讨论更加容易和更有效的方式以完成同L(fng)目标,使用U定俗成的配|?注释和零配置插g.

在我们进入详l讲解核心构成之前我们先来讨Z下全局的配|?

Configuration

在配|Struts2之前,你需要先下蝲发行版或是在你的Maven2?pom.xml"文g中配|它的依赖关p?
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.0.6</version>
</dependency>
做完之后,Struts2应用的配|就可以分成三个独立的文?如图2中所C?

Figure 2: Configuration file scope for framework elements

需要在你的"web.xml"文g里ؓ(f)WEB应用的配|FilterDispatcher Servletqo(h)?
1 <filter>
2     <filter-name>action2</filter-name>
3     <filter-class>
4         org.apache.struts2.dispatcher.FilterDispatcher
5     </filter-class>
6 </filter>
7 <filter-mapping>
8     <filter-name>action2</filter-name>
9     <url-pattern>/*</url-pattern>
10 </filter-mapping>
11
它配|了基本的WEB应用.剩下来的事就是?struts.properties"配置文g来自定义WEB应用的执行环?通过"struts.xml"配置文g来配|WEB应用的构?我们现在来看看这两个配置文g的详l描q?

The struts.properties File

q个配置文g提供了一个改变框枉认行为的机制.一般情况下,你是不需要修改这个文件的,一个例外是你想配置一个对于开发者友好的调试环境.所有的包含?struts.properties"配置文g中的配置?都可以?init-param"标签配置?web.xml"文g?同样也可以?constant"标签配置?struts.xml"配置文g?

Properties允许修改如改变Freemarker选项,替换action的映类,军_是否重新加蝲XML配置文g,默认使用的用L(fng)面主题等{?更多的关于properties的最C?h阅位?a target="_blank" rel="external">http://struts.apache.org/2.x/docs/strutsproperties.html的Struts2的Wiki.

一个默认的名ؓ(f)"default.properties"配置文g包含在发行版的Struts2-Core JAR文g?惌修改一个配|项,只需在你目的源文g的类路径的根目录里创Z个名?struts.properties"的文?之后,d你想修改的配|项.新的值将覆盖掉默认?

在开发环境中,q有一些配|项你可能需要更?

struts.i18n.reload = true -- 能够重新加蝲国际化文?
struts.devMode = true -- 能够在开发模式下提供更全面的调试
struts.configuration.xml.reload = true 能够重新加蝲XML配置文g(适用于action),修改之后可以在Servlet容器里重新加载整个WEB应用
struts.url.http.prot = 8080 -- 讄服务q行的端?以便生成正确的URL)
The struts.xml File

"struts.xml"文g包含配置信息,你将修改它用于发布action,我们在本章剩余的部分详l的讲解指定的元?现在,让我们看看不?x)改变的l构.

?
Ҏ(gu)你应用的功能,可能?x)从你的应用中移?struts.xml"文g.配置上我们将在本章讨ZU替换的Ҏ(gu),使用注释,"web.xml"启动参数,和交替的URL映射配置.
唯一的配|仍焉?struts.xml"文g,如全局l果,异常处理,和自定义的拦截器?

q是一个XML文g,所以第一个元素是XML的版本和~码信息.下一个则是XML的文档类型定?DTD).DTD提供了一些文仉的元素的l构,q最l用XML来解析和~辑.
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE struts PUBLIC
3     "-//Apache Software Foundation//DTD Struts Configuration
4     2.0//EN"
5     "http://struts.apache.org/dtds/struts-2.0.dtd">
6 <struts>
7     <package
8         name="struts2"
9         extends="struts-default"
10         namespace="/struts2">
11         …
12     </package>
13 </struts>
我们现在到达?lt;struts>标签.q是Struts2具体配置的最外层标签.所有其他的标签都将被包含在q个当中.

The Include Tag:

<include ... />标签用于Struts2应用模块化时引入其他配置文g时用ƈ且它始终?lt;struts>标签的子标签.它仅仅包含一?file"属?用于提供被引入的文g的名U?那个文g必须?struts.xml"配置文g的结构相?例如,如果你想拆分一个计费应用的配置文g,你可以选择按组缴?理和报表配|到单独的文件中:
1 <struts>
2     <include file="billing-config.xml" />
3     <include file="admin-config.xml" />
4     <include file="reports-config.xml" />
5     …
6 </struts>
引入文g?序是重要的.来自引入文g的信息将在文件中引入标签的位|开始有?因此,使用一个配|在另一个文件中的标{?q个引入的配|必d现在被引用之?

有一些文件你是必L的引入,q有一些文件是自动引入?比如?struts-default"?struts-plugin.xml".两者都包含了默认的l果cd,拦截?拦截器栈,?以及(qing)WEB应用执行环境的配|信?也可以配|在"struts.properties"文g?的配|?区别在于"struts-default.xml"文g提供的是Struts2的核心配|??struts-plugin.xml"提供的是详细插g的配|?每个插gJAR文g中都应包含一?struts-plugin.xml"文g,所有这些都在启动的时候加?

西瓜 2009-05-29 22:41 发表评论
]]>
ThreadLocal在spring框架中的作用 http://m.tkk7.com/ashutc/archive/2009/05/29/278954.html西瓜西瓜Fri, 29 May 2009 14:36:00 GMThttp://m.tkk7.com/ashutc/archive/2009/05/29/278954.htmlhttp://m.tkk7.com/ashutc/comments/278954.htmlhttp://m.tkk7.com/ashutc/archive/2009/05/29/278954.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/278954.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/278954.html

我们知道Spring通过各种DAO模板c降低了研发者用各U数据持久技术的隑ֺ。这些模板类都是U程安全的,也就是说Q多个DAO能够复用同一个模板实例而不?x)发生冲H?

我们使用模板c访问底层数据,Ҏ(gu)持久化技术的不同Q模板类需要绑定数据连接或?x)话的资源。但q些资源本n是非U程安全的,也就是说他们不能在同一时刻被多个线E共享?

虽然模板c通过资源池获取数据连接或?x)话Q但资源池本w解决的是数据连接或?x)话的缓存问题,q数据q接或会(x)话的U程安全问题?

按照传统l验Q假如某个对象是非线E安全的Q在多线E环境下Q对对象的访问必采用synchronizedq行U程同步。但Spring的DAO模板cdƈ未采用线E同步机Ӟ因ؓ(f)U程同步限制了ƈ发访问,?x)带来很大的性能损失?

此外Q通过代码同步解决性能安全问题挑战性很大,可能?x)增强好几倍的实现隑ֺ。那模板cȝ竟Ԓ丈何U魔法神功,能够在无需同步的情况下化解线E安全的N呢?{案是ThreadLocalQ?

ThreadLocal在Spring中发挥着重要的作用,在管理request作用域的Bean、事务管理、Q务调度、AOP{模块都出现了他们的w媄(jing)Qv着举轻重的作用。要想了解Spring事务理的底层技术,ThreadLocal是必L克的山头堡垒?

ThreadLocal是什?

早在JDK 1.2的版本中提供java.lang.ThreadLocalQThreadLocal军_U程E式的ƈ发问题提供了一U新的思\。用这个工L(fng)能够很简z地~写Z的多线E程式?

ThreadLocal很容易让人望文生义,惛_然地认ؓ(f)是个“本地U程”。其实,ThreadLocalq不是个ThreadQ而是Thread的局部变量,也许把他命名为ThreadLocalVariable更容易让人理解一些?

当用ThreadLocall护变量ӞThreadLocal为每个用该变量的线E提供单独的变量副本Q所以每一个线E都能够单独地改变自q副本Q而不?x)?jing)响其他线E所对应的副本?

从线E的角度看,目标变量p是线E的本地变量Q这也是cd?#8220;Local”所要表辄意思?

U程局部变量ƈ不是Java的新发明Q很多语aQ如IBM IBM XL FORTRANQ在语法层面提供线E局部变量。在Java中没有提供在语言U支持,而是变相地通过ThreadLocal的类提供支持?

所以,在Java中编写线E局部变量的代码相对来说要笨拙一些,因此造成U程局部变量没有在Java研发者中得到很好的普?qing)?

ThreadLocal的接口方?

ThreadLocalcL口很单,只有4个方法,我们先来了解一下:(x)

    * void set(Object value)

配置当前U程的线E局部变量的倹{?

    * public Object get()

该方法返回当前线E所对应的线E局部变量?

    * public void remove()

当前线E局部变量的值删除,目的是ؓ(f)了减内存的占用Q该Ҏ(gu)是JDK 5.0新增的方法。需要指出的是,当线E结束后Q对应该U程的局部变量将自动被垃圑֛Ӟ所以显式调用该Ҏ(gu)清除U程的局部变量ƈ不是必须的操作,但他能够加快内存回收的速度?

    * protected Object initialValue()

q回该线E局部变量的初始|该方法是个protected的方法,昄是ؓ(f)了让子类覆盖而设计的。这个方法是个gq调用方法,在线E第1ơ调用get()或set(Object)时才执行Qƈ且仅执行1ơ。ThreadLocal中的~省实现直接q回一个null?



西瓜 2009-05-29 22:36 发表评论
]]>
Spring XML配置实践http://m.tkk7.com/ashutc/archive/2009/03/09/258594.html西瓜西瓜Mon, 09 Mar 2009 06:39:00 GMThttp://m.tkk7.com/ashutc/archive/2009/03/09/258594.htmlhttp://m.tkk7.com/ashutc/comments/258594.htmlhttp://m.tkk7.com/ashutc/archive/2009/03/09/258594.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/258594.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/258594.html 

Spring是一个强大的Java应用框架Q它q泛地应用于Java应用E序中,为Plain Old Java ObjectsQPOJOQ提供企业服务。Spring利用依赖注入机制来简化工作,同时提高可测试性。其配置文gQ通常是XML格式Q中指定了Spring bean、依赖性以?qing)bean所需的服务。但是,q些XML配置文g既冗长又不实用。对于需要定义大量Spring bean的大型项目来_(d)它们难以阅读和管理?br /> 在本文中Q我向(zhn)展C?2U用于Spring XML配置的最?jng)_c(din)其中的一些实践与其说是最?jng)_践,倒不如说是必要实c(din)注意,其他因素Q如域模型的讄Q也可能影响XML的配|,但是本文重点研究XML配置的可L和可管理性?/p>

1。避免用自动绑定(autowiringQ功?/strong>
Spring可以通过beancȝ自省自动l定依赖性,所以不必显式指明bean的属性和构造函数。Bean属性可以通过属性名U或cd匚w来实现自动绑定。构造函数通过cd匚w来实现自动绑定。甚臛_以指定自动检autowiring模式Q它可以引导Spring选择一U适当的运行机制。先来看看下面的一个例子:(x)
    <bean id="orderService"
        class="com.lizjason.spring.OrderService"
        autowire="byName"/>
OrderServicecȝ属性名在容器中用于匚wbean实例。自动绑定可能会(x)节省一些键入工作量q减؜乱。但是在现实目中不应该使用q种方式Q因为它牺牲了配|的可读性和可维护性。许多指南和介绍中大肆吹捧自动绑定是Spring的一Ҏ(gu)好的Ҏ(gu),而没有提到这一Ҏ(gu)所带来的牺牌Ӏ依我来看,q就像Spring中的对象池(objectQpoolingQ,更大E度上只是宣传的噱头。对于精XML配置文g来说Q它是一个好办法Q但它实际上增加了复杂性,其是在q行包含大量cd明的目时。虽然Spring允许混合使用自动l定和显式绑定,但这?x)XML配置更加晦ӆ难懂?/p>

2.使用命名U定
该原则对于Java~码也一样适用。在目中用清晰的、描q性的、一致的命名U定非常有利于开发h员理解XML配置。例如,对于bean IDQ可以按照JavacdD名U定来命名它。OrderServiceDAO实例的bean ID应该命名为orderServiceDAO。对于大型项目,可以在bean ID前面加上包名作ؓ(f)前缀?/p>

3. 使用zŞ?/strong>
zŞ式避免了冗长Q因为它?yu)属性值和引用从子元素中移入属性中。例如下面的例子Q?br />     <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <property name="companyName">
            <value>lizjason</value>
        </property>
        <constructor-arg>
            <ref bean="orderDAO">
        </constructor-arg>
    </bean>
可以使用zŞ式将上述代码重写为:(x)
    <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <property name="companyName"
            value="lizjason"/>
        <constructor-arg ref="orderDAO"/>
    </bean>

zŞ式自1.2版本起就可以使用。注意,对于<ref local="...">Q没有简zŞ式?br /> zŞ式不但可以节U键入工作量Q而且可以使XML配置文g更清晰。当一个配|文件中定义了大量的cLQ它可以显著提高可读性?/p>

4. 对于构造函数参数匹配,cd比下标好
当构造函数含有一个以上同U类型的参数Q或者属性值的标签已经被占用时QSpring允许使用?开始的下标来避免؜淆。例如:(x)
    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <constructor-arg index="0" value="lizjason"/>
        <constructor-arg index="1" value="100"/>
    </bean>
利用type属性来~写?x)更好一些,如下Q?br />     <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <constructor-arg type="java.lang.String"
            value="lizjason"/>
        <constructor-arg type="int" value="100"/>
    </bean>

使用index可以减少一些代码,但是与type属性相比,它更易于出错且难于阅诅R只有在构造函数参C明确的时候,才应该用index?/p>

5. 可能重用已定义的bean
Spring提供了一U类gl承的机制来减少配置信息的复制ƈ化XML配置。定义一个子c,它就可以从父c那里扉K|信息,而父cd际上成ؓ(f)子类的一个模ѝ这是大型目中所谓的重用。只需在父cbean中设|a(chn)bstract=trueQ然后在子bean中指定parent引用。例如:(x)
    <bean id="abstractService" abstract="true"
        class="com.lizjason.spring.AbstractService">
        <property name="companyName"
            value="lizjason"/>
    </bean>

    <bean id="shippingService"
        parent="abstractService"
        class="com.lizjason.spring.ShippingService">
        <property name="shippedBy" value="lizjason"/>
    </bean>

ShippingServicecMabstractServicecȝ承companyName属性的值——lizjason。如果一个bean没有指定cL工厂Ҏ(gu)Q那么这个bean便是抽象的?/p>

6. 在导入时Q首选通过ApplicationContext来汇~bean定义
像Ant脚本中的导入一PSpring的import元素对于汇编模块化的bean定义来说是很有用的。例如:(x)
    <beans>
        <import resource="billingServices.xml"/>
        <import resource="shippingServices.xml"/>
        <bean id="orderService"
            class="com.lizjason.spring.OrderService"/>
    <beans>

然而,相对于用import在XML配置中进行预汇编Q通过ApplicationContext来配|这些bean则显得更加灵zR用ApplicationContext的话QXML配置也更易于理。可以向ApplictionContext构造函C递一lbean定义Q如下:(x)
    String[] serviceResources =
        {"orderServices.xml",
        "billingServices.xml",
        "shippingServices.xml"};
    ApplicationContext orderServiceContext = new
        ClassPathXmlApplicationContext(serviceResources);

7. 使用id作ؓ(f)bean标识W?/strong>
可以指定一个id或名U来作ؓ(f)bean标识W。虽然用id不能提高可读性,但是它可以利用XML分析E序来对bean引用q行验证。如果由于XML IDREF的约束而不能用某个idQ那么可以用名U来作ؓ(f)bean的标识符。XML IDREF的约束是Qid必须以字母(或者XML规范中定义的标点W号Q开_(d)后面是字母、数字、连字符、下划线、冒h句点。实际上Q很会(x)遇到XML IDREFU束问题?/p>

8. 在开发阶D用依赖性检查(dependency-checkQ?/strong>
可以在bean定义中ؓ(f)dependency-check属性设|一个非默认|比如simple、objects或allQ以便容器进行依赖性检查。当需要显式或通过自动l定讄bean的全部属性(或某cd性)Ӟ依赖性检查便昑־很有用?br />     <bean id="orderService"
        class="com.lizjason.spring.OrderService"
        dependency-check="objects">
        <property name="companyName"
            value="lizjason"/>
        <constructor-arg ref="orderDAO"/>
    </bean>

在这个例子中Q容器确保ؓ(f)orderService bean讄的属性不是primitives或collections。也可以为所有的bean讄默认依赖性检查,但是我们很少q样做,因ؓ(f)有些bean属性根本就不必讄?/p>

9. 为每个配|文件添加首部注?/strong>
最好用描q性的id和名U来取代XML配置文g中的内置注释。此外,d一个配|文仉部也很有用,它可以概q文件中所定义的bean。可以选择描q添加到description标签中。例如:(x)
    <beans>
        <description>
            This file defines billing service
            related beans and it depends on
            baseServices.xml,which provides
            service bean templates...
        </description>
        ...
    </beans>
使用description标签的一个好处是可以L地利用工具从标签中选获取描q内宏V?/p>

10. 对于更改Q团队成员要U极交流
在重构Java代码Ӟ需要随时更新配|文件ƈ通知团队成员。XML配置文g也是代码Q它们是应用E序的至关重要的部分Q但是它们难于阅dl护。大部分情况下,需要同旉读XML配置文g和运行中的Java代码?/p>

11. Setter注入优于构造函数注?/strong>
Spring提供?U类型的依赖注入Q构造函数注入(constructor injectionQ、setter注入Qsetter injectionQ和Ҏ(gu)注入Qmethod injectionQ。我们一般只用前两种?br />     <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <constructor-arg ref="orderDAO"/>
    </bean>

    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <property name="billingDAO"
            ref="billingDAO">
    </bean>

在这个例子中QorderServicecM用的是构造函数注入,而BillingServicecM用的是setter注入。构造函数注入可以确保bean不会(x)在一个非法状态下被创建,但是setter注入更加灉|且更易于理Q尤其是在类包含许多属性ƈ且其中一些可选的情况下?/p>

12. 不要滥用依赖注入
最后一点,Spring ApplicationContext可以为?zhn)创徏Java对象Q但q不是所有的Java对象都应通过依赖注入来创建。例如,全局对象不应该通过ApplicationContext来创建。Spring是一个很的框架Q但是,可L和易管理性而言Q如果定义了大量beanQ基于XML的配|就可能成ؓ(f)问题。过度用依赖注入会(x)使XML配置变得复杂且臃ѝ要知道Q借助于功能强大的IDEQ如Eclipse和IntelliJQ,Java代码比XML文g更加易读、易l护、易理?/p>

l束?/strong>
XML是通用的Spring配置方式。但如果定义了大量beanQ基于XML的配|就?x)变得冗长而不实用。Spring提供了丰富的配置选项Q恰当地利用其中的选项可以使XML配置更清晎ͼ但是Q有些选项Q如autowiringQ往往?x)降低配|文件的可读性和可维护性。遵循本文中所描述的最?jng)_践,有助于(zhn)创建出清晰易读的XML配置文g?/p>

西瓜 2009-03-09 14:39 发表评论
]]>
配置WebWorkhttp://m.tkk7.com/ashutc/archive/2009/03/03/257483.html西瓜西瓜Tue, 03 Mar 2009 02:27:00 GMThttp://m.tkk7.com/ashutc/archive/2009/03/03/257483.htmlhttp://m.tkk7.com/ashutc/comments/257483.htmlhttp://m.tkk7.com/ashutc/archive/2009/03/03/257483.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/257483.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/257483.html
    1. 基本配置

       . action?br />        . actionc?br />        . resultcd

   

    <xwork>
        <include file="webwork-default.xml">
        <package extends="webwork-default" name="default">
        <default-action-ref name="home">

        <action>
                       
                        name="helloWorld"
                       
                        class="ch2.example1.HelloWorld">
                   
            <result name="input">login.jsp</result>
            <result type="redirect" name="success">/index.jsp</result>
        </action>
        </default-action-ref>
    </package>       

        以上例子中,如果helloWorld actionq回的result code是SUCCESSQ那么用户将?x)重定向?index.jsp。如果返回的
        result code是INPUTQ将?x)显Clogin.jsp面?br />
    2.  配置别名重用action

        多个名字映到相同的actionc;q个名字UCؓ(f)别名。这时多个请求访问相同的execute()Ҏ(gu)Q?br />
        在别名基上,可增加一个可选的method属性,指定webwork该调用哪个方法。所指定的方法格式与execute()Ҏ(gu)一栗?br />         q时多个h讉K不同的方法;

        <action class="ch2.example1.Cal" name="add">
            <result name="success">cal.jsp</result>          
        </action>
       
        <action method="minus" class="ch2.example1.Cal" name="minus">
            <result name="success">cal.jsp</result>          
        </action>        

        注:(x)WebWork通过xwork.xml映射x法有两种途径Q?br />             . 通过查找与method属性的g致的Ҏ(gu)Q?br />             . 通过查找doMethod()形式的方法;

            WebWork先找method属性一致方法,如找不到Q再找doMethod()形式Ҏ(gu)Q?br />
    3.  不配|别名重用action

        通过name!method.action形式h讉Ka(chn)ctionQ其中name为action的映名字。这时不需额外配置?br />
        注:(x)优先推荐Q但要预防不怀好意的用户通过该途径使用你不惌用户调用的方法;

    4.  通过参数自定义action

        可通过在配|文件中讄参数传递给action. 从而达到非常灵z设|的目的?br />
        a. 在xwork.xml文g的action配置位置处配|以下信?配置参数名称为url)Q?br />
           <action class="ch2.example1.ParamTest" name="paramTest">
              <result name="success">paramTest.jsp</result>
             
           </action> 

        b. action

           在action中定义与参数名同名的属性以?qing)对应的setter/getterҎ(gu)Q?span class="hilite1">webwork在action执行时会(x)自动调用
           setterҎ(gu)为属性赋在xwork.xml文g中所配置的参数|

        c. jsp

           通过标记: <ww:property value="属性名">  获取参数|

? 配置Result

    1.  基本配置Q?br />
        <result type="redirect" name="success">paramTest.jsp</result>

        result׃个部分组?
        . result映射Q?通过name属性指定result的逻辑名,name的属性gaction中execute()Ҏ(gu)中的q回值相?
                       result标记本体内容指定跌{的\径,既可以ؓ(f)l对路径(/代表包含namespace内容在内的web应用根\?Q?br />                        也可以ؓ(f)相对路径Q?br />         . resultcdQ?通过type属性指定,默认gؓ(f)dispatcherQ可以指定ؓ(f)redirect。如指定为redirectQ则产生
                       一个新的请求蟩转至目的地址Q?br />
    2.  使用全局result映射减少重复配置

        讑֮全局resultQ服务于多个action配置Q减重复配|;

        <global-results>
            <result type="redirect" name="success">paramTest.jsp</result>
    </global-results>
        <action class="ch2.example1.ParamTest" name="paramTest">

? 配置interceptor

    interceptor(拦截?是一U很Ҏ(gu)的对象,它围l着action?qing)result的执行过E。它可以在action之前或之后及(qing)result
    之后工作Q实C某些逻辑的松耦合Q譬如安全、日志和校验?br />
    1.  定义interceptor

        . 定义

          <package name="webwork-default">
               <interceptors>
                    <interceptor class="com.opensymphony.xwork.interceptor.LoggingInterceptor" name="logger">
                    <interceptor class="com.opensymphony.xwork.interceptor.TimerInterceptor" name="timer">
               </interceptor>
          </interceptor>

          注:(x)一般不需自行定义Q在webwork-default.xml文g中已定义了很多interceptor?span class="hilite1">webwork-default.xml位于
              webwork-2.2.4.jar文g根目录中;

        . 使用

          <package name="webwork-default">
               <interceptors>
                    <interceptor class="com.opensymphony.xwork.interceptor.LoggingInterceptor" name="logger">
                    <interceptor class="com.opensymphony.xwork.interceptor.TimerInterceptor" name="timer">
               </interceptor>
               <action class="ch2.example1.ParamTest" name="paramTest">
                    <interceptor-ref name="timer">
                    <interceptor-ref name="logger">
               </interceptor-ref> 
          </interceptor-ref>
       
        q样讄后,当paramTest.action被调用的时侯Qtimer和logger两个interceptor也会(x)相应地被调用?br />
    2.  多个interceptorl合为栈

        多个interceptorl合CP而不需要ؓ(f)每一个action声明数量众多?lt;interceptor-ref>。一个interceptor栈包?br />         一linterceptorQƈ且按照它们本w在栈中定义的顺序来执行?br />
        . 定义

          <package name="webwork-default">
               <interceptors>
                    <interceptor class="com.opensymphony.xwork.interceptor.LoggingInterceptor" name="logger">
                    <interceptor class="com.opensymphony.xwork.interceptor.TimerInterceptor" name="timer">
               </interceptor>
           
               <interceptor-stack name="myStack">
                    <interceptor-ref name="logger">
                    <interceptor-ref name="timer">
               </interceptor-ref>
          </interceptor-ref>         

        . 使用       

          <package name="webwork-default">
               <interceptors>
                    <interceptor class="com.opensymphony.xwork.interceptor.LoggingInterceptor" name="logger">
                    <interceptor class="com.opensymphony.xwork.interceptor.TimerInterceptor" name="timer">
               </interceptor>
           
               <interceptor-stack name="myStack">
                    <interceptor-ref name="logger">
                    <interceptor-ref name="timer">
               </interceptor-ref>

               <action class="ch2.example1.ParamTest" name="paramTest">
                    <interceptor-ref name="myStack">
               </interceptor-ref>
          </action>         

    3.  使用默认interceptor-ref减少重复配置

        通过使用default-interceptor-ref元素Qpackage中每一个action都不再需要定义Q何interceptor?br />
           <package name="webwork-default">
               <interceptors>
                    <interceptor class="com.opensymphony.xwork.interceptor.LoggingInterceptor" name="logger">
                    <interceptor class="com.opensymphony.xwork.interceptor.TimerInterceptor" name="timer">
               </interceptor>
           
               <interceptor-stack name="myStack">
                    <interceptor-ref name="logger">
                    <interceptor-ref name="timer">
               </interceptor-ref>

               <default-interceptor-ref name="myStack">

               <action class="ch2.example1.ParamTest" name="paramTest">
          </action>      

        注:(x)如ؓ(f)一个action定义了interceptorQ那么这个action不再用默认的interceptor?br />
? 高配置

    1.  package

        WebWork中的package和Java中的package在很多方面非常相|它将多个actionl织成一个模块。简化维护工作,提高
        重用性。一个package中包含了所有将用到的action, result, interceptor的定义?br />
    2.  扩展package

        WebWork中的package可以扩展另外的packageQؓ(f)其extends属性指定一个用逗号分隔的package列表Q从而扩展该列表?br />         package。当一?span class="hilite1">WebWork package扩展另外一个packageӞ会(x)从被包含的package中复制所有的定义Qƈ在自己本w?br />         已有的定义基上增加这些配|。这让你可以配|的公共部分集中hQ减package中重复定义的内容?br />
        <package extends="webwork-default" name="default">
        ...
        </package>

    3.  映射namespace

        WebWork通过action名字和所属的namespace标识action。如果package没定义namespace属性,用默认的namespace: "/"?br />         ?span class="hilite1">WebWork接收C个请求的时侯Q?span class="hilite1">WebWork?x)将h的URL分ؓ(f)namespace和action名字两个部分Q然后从xwork.xml中查?br />         namespace/action内容Q如果没有找刎ͼ则从默认的namespace中查找action?br />
        <package namespace="/enterinfo" extends="webwork-default" name="default">
            <action class="ch2.example1.ParamTest" name="paramTest">
                   
                <result type="redirect" name="success">paramTest.jsp</result>
                </action>
        </package>

        以上讉KparamTestQ通过URL: http://localhost:8080/enterinfo/paramTest.actionQ其中:(x)
        . /enterinfo为namespace的名字;
        . paramTest为action的名字;

        多个package可以使用相同的namespace?br />
    4.  使用include标签实现lg?br />
        Z支持应用程序划分ؓ(f)更容易管理的模块Q?span class="hilite1">WebWork提供了一U包含机Ӟ可以xwork.xml划分为多个文Ӟ而每一?br />         子文件又是与一个模块相联系的。可以通过使用<include>标签指定文g名的Ҏ(gu)子文g包含到xwork.xml中,?span class="hilite1">WebWork
        ׃(x)在应用程序的classpath中查找指定的子文件?br />
       
        <xwork>
             <include file="webwork-default.xml">            
             <package namespace="/enterinfo" extends="webwork-default" name="default">
             ...
             </package>
        </include>
 
? 其它配置

    1. web.xml

   
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4">
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
        <servlet>
            <servlet-name>webwork</servlet-name>
            <servlet-class>
                com.opensymphony.webwork.dispatcher.ServletDispatcher
            </servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>webwork</servlet-name>
            <url-pattern>*.action</url-pattern>
        </servlet-mapping>
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
        <jsp-config>
            <taglib>
                <taglib-uri>webwork</taglib-uri>
                <taglib-location>
                    /WEB-INF/lib/webwork-2.2.4.jar
                </taglib-location>
            </taglib>
        </jsp-config>
    </web-app>      

    2. webwork.properties

       xwork.xml定义了action映射Qƈ且将interceptor和result应用到这些action上。?span class="hilite1">webwork.properties用来定义
       application范围的设|,以及(qing)能够改变框架功能的配|参数?br />
       WebWork首先?x)装载位?span class="hilite1">WebWork JAR文g中的default.propertiesQ然后再装蝲webwork.propertiesQƈ且根?br />        webwork.properties内容改写之前装蝲的配|设定?lt;/xwork></include></default-interceptor-ref></interceptor-ref></interceptor-stack></interceptor></interceptors></package> </interceptor-ref></interceptor-stack></interceptor></interceptors></package> </interceptor-stack></interceptor></interceptors></package> </interceptor-ref></action></interceptor></interceptors></package> </interceptors></package> </action></ww:property></include></xwork>

西瓜 2009-03-03 10:27 发表评论
]]>
վ֩ģ壺 þþƷձҰ| þ޾Ʒ˳ۺ| պþ| һ| һػɫѴƬƵ| Ƶ߲| ޹պۺ| ޹Ʒxo߹ۿ| ľƷ| 18ڵվ| þþƷۺר| þþþ޹AV鶹| ִӲëƬ| һŷĻ| һ| ޳AV߲| һѻɫƬ| ޳aƬ߹ۿ| ҹWWWʪˬ| ޹߹ۿ| ˳˳ۺ| ŮˬƵ| ȫ»ɫؼվ | ѿڿŮ| ëƬ߲| þþƷƷëƬ| 91Ƶ| ߲| ձѹۿ| ޹Ʒþþ| һëƬѿ| 99ƷƵ| 97Ƶѹۿ| ޹Ʒһߵ| AëƬav| ձ߿Ƭ| ƬAVƬѹۿ| þAV뾫Ʒɫҹ| ó˾þAvѸ| պƷһAVۿ| ֻ߿avƬ|