假设有命名空间x
XSD:http://www.springframework.org/schema/x/spring-x-3.0.xsd
位置:org/springframework/aop/config/spring-x-3.0.xsd
xmlns:x=”http://www.springframework.org/schema/x”
引入命名空间x的声明
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.springframework.org/schema/x" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/x http://www.springframework.org/schema/x/spring-x-3.0.xsd > ………… Spring配置信息 </beans>
可叠加
历史上, Spring 的配置最初只涵盖 XML 方式。但是 Spring 渐渐也与基于 annotation 的配置方式打成一片。到了 Spring2.5 ,已经提供超过 36 个 annotation 的支持了,这还不包括第三方类库和 Spring add-ons 。
这一组 annotations 主要是让 Spring 来创建和注入 bean 对象的。
@Transactional annotation 协同 <tx:annotation-driven> 元素用来为类或方法声明事务边界和规则
这组 annotations 主要用在应用程序中各个层次中的 stereotype 类型。如果在 Spring 配置文件中还配置了 <context:component-scan> 元素,而且某个类还被标注了下列 annotation 的话,该类就会自动被注册到 Spring context 中去。
另外,如果一个 PersistenceExceptionTranslationPostProcessor 配置在 Spring context 中,那么任何标记了 @Repository annotation 的 bean 在方法执行过程中抛出的 SQLExceptions 会被转换成 Spring 的 unchecked DataAccessExceptions
这组 annotations 到 Spring2.5 时才被引入。它让 Spring MVC 应用程序的创建变得更加容易,不仅将 XML 配置文件缩减到最小化,而且不需要去继承 Controller interface 的实现了。
这组 annotations 协同 <context:mbean-export> 元素,将 bean 的方法和属性声明为 MBean 的操作和属性。
这组 annotations 主要用来建立 JUnit4 风格的单元测试,但前提是得依赖于 Spring context 中定义的 beans 或一个 transactional context 。
XSD:http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
位置:org/springframework/aop/config/spring-aop-3.0.xsd
xmlns:aop=http://www.springframework.org/schema/aop
<aop:aspectj-autoproxy />配合注释@Aspect使用要求jdk1.5以上版本
定义一个Aspect
package com.sarkuya.aop.aspect; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class SampleAspect { @Before("execution(* com.sarkuya.service..*.*(..))") public void doBeforeInServiceLayer() { System.out.println("Aop: do before in Service layer"); } }
在Spring文件中声明<aop:aspectj-autoproxy />和上面类的bean
<aop:aspectj-autoproxy /> <bean class="com.sarkuya.aop.aspect.SampleAspect" />
当用户调用com.sarkuya.service包中任一类的任一方法,在调用前,Spring将自动执行下面的doBeforeInServiceLayer()方法,此方法只是简单地打印一些信息
上面的Aspect中混杂了Pointcut及Advice,可以将其分开
定义Pointcut,方法签名必须是public及void型
package com.sarkuya.aop.aspect; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; @Aspect public class SampleAspect { @Pointcut("execution(* com.sarkuya.service..*.*(..))") public void inServiceLayer() {} }
定义Advice
package com.sarkuya.aop.advice; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class SampleAdvice { @Before("com.sarkuya.aop.aspect.SampleAspect.inServiceLayer()") public void logInfo() { System.out.println("Aop: do before in service layer"); } }
<aop:aspectj-autoproxy /> <bean class="com.sarkuya.aop.advice.SampleAdvice"/>
只需配置SampleAdvice,无需配置SampleAspect。
下面有一个例程来直观的展示如何使用<aop:config/>标签来配置Spring AOP(完整代码见例程4.15)。在例子中,我们使用<aop:config/>配置一个切面并拦截目标对象Peoples的 SayHello()方法,在它执行前输出提示信息。
package aop.test; public class People{ public String SayHello(String str){ System.out.println(this.getClass().getName()+ "说:"+str); return str; } }
package aop.test; import org.aspectj.lang.JoinPoint; public class MyAspect { public void beforeAdvice(JoinPoint point) { System.out.println("前置通知被触发:" + point.getTarget().getClass().getName()+ "将要" + point.getSignature().getName()); } }
<bean id="MyAspect" class="aop.test.MyAspect" /> <bean id="TestBean" class="aop.test.People" /> <aop:config proxy-target-class="true"> <aop:aspect ref="MyAspect" order="0" id="Test"> <aop:pointcut id="testPointcut" expression="execution(* aop..*(..))" /> <aop:before pointcut-ref="testPointcut" method="beforeAdvice" /> </aop:aspect> </aop:config>
XSD:http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
位置:org/springframework/beans/factory/xml/spring-beans-3.0.xsd
xmlns=”http://www.springframework.org/schema/beans”
默认Spring bean的声明
Bean 命名空间下的元素简介
XSD:http://www.springframework.org/schema/tool/spring-tool-3.0.xsd
位置:org/springframework/beans/factory/xml/spring-tool-3.0.xsd
xmlns:tool=”http://www.springframework.org/schema/tool”
使用在其他命名空间的的xsd文件中,使Spring支持自定义命名空间,不直接使用在Spring配置中
XSD:http://www.springframework.org/schema/util/spring-util-3.0.xsd
位置:org/springframework/beans/factory/xml/spring-util-3.0.xsd
xmlns:utill=http://www.springframework.org/schema/util
1. <util:constant/>元素
将静态字段托管为bean
public static final String hwStatic = "hello static";
<util:constant id="hwConstant" static-field="test.HelloWorld.hwStatic"/>
<util:property-path id="property-path" path="helloWorld.hello"/> <bean id="helloWorld"> <property name="hello" value="hi"/> </bean>
这里path=”helloworld.hello”就是指bean为”helloworld”的属性hello。
“classpath:”表明,将从类路径上查找并装载xxx属性文件.
<util:properties id="xxx" location="classpath:xxxxx.properties">
<util:list id="listUtil" list-class="java.util.ArrayList"> <value>first</valuse> <value>two</valuse> <value>three</valuse> <value>ten</valuse> </util:list>
它的作用就是在spring启动初始化bean时,给listUtil这个list赋值为这四个值
<util:map id="mapUtil" map-class="java.util.HashMap"> <entry key="1" value="first"> <entry key="2" value="two"> <entry key="3" value="three"> </util:map>
<util:set id="setUtil" set-class="java.util.HashSet"> <value>first</value> <value>two</value> <value>three</value> </util:set>
分页
XSD:http://www.springframework.org/schema/context/spring-context-3.0.xsd
位置:org/springframework/context/config/spring-context-3.0.xsd
xmlns:context=”http://www.springframework.org/schema/context”
context 命名空间主要用来提供多种 application context 特定的配置。它包括:支持基于 annotation 的配置方式, JMX 以及领域对象 (domain object) 的注入。
<context:component-scan> 元素会自动扫描指定包下的类,并自动将那些标记有 @Component, @Controller, @Repository, @Service 或 @Aspect. 的类全部注册到 Spring 容器中。
使用外部配置文件,我们可以使用 <context:property-placeholder>
<context:property-placeholder location=”file:////etc/pirate.properties” />
定义在 /etc/pirate.properties 属性文件中的那些键值对现在可以在 Spring 配置文件中调用
<bean id=”pirate” class=”Pirate”> <constructor-arg value=”${pirate.name}” /> </bean>
分页
XSD:http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
位置:org/springframework/ejb/config/spring-jee-3.0.xsd
xmlns:jee=http://www.springframework.org/schema/jee
<jee:remote-slsb id=”hispaniola” jndi-name=”ejb/PirateShip” business-interface=”com.pirate.PirateShipEjb” resource-ref=”true” /> <jee:jndi-lookup id=”parrot” jndi-name=”pirate/Parrot “ resource-ref=”false” />
第一个元素 <jee:remote-slsb> 配置了一个叫“ Hispaniola ”的 bean ,它实际上引用的是一个 EJB2 的 remote stateless session bean 。这里 EJB 的 home interface 可以通过 JNDI 名称“ java:comp/env/ejb/PirateShip ”找到。属性“ resource-ref ”表示应该值会自动加上“ java:comp/env/ ”前缀。 EJB 的实现方法定义在 PirateShipEjb 业务接口中。
另一个元素 <jee:jndi-lookup> 用于从 JNDI 获取对象的引用(它可以是一个 EJB3 session bean 或一个普通 pojo )。对象会在这个叫“ pirate/Parrot ”的 JNDI 中获得。注意这里我们将“ resource-ref ”属性配置为“ false ”,所以应该 jndi-name 不会加上“ java:comp/env ”前缀。
XSD:http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
位置:org/springframework/scripting/config/spring-lang-3.0.xsd
xmlns:lang=http://www.springframework.org/schema/lang
<bean id=”jackSparrow” class=”Pirate”> <constructor-arg value=”Jack Sparrow” /> <property name=”compass” ref=”compass” /> <property name=”hat” ref=”hat” /> </bean> <lang:groovy id=”compass” script-source=”classpath:Compass.groovy” refresh-check-delay=”10000” /> <lang:jruby id=”hat” script-source=”classpath:PirateHat.rb” script-interface=”PirateHat” refresh-check-delay=”60000” />
<lang:groovy> 元素建了一个由 Groovy script 实现的 bean ,名字叫 Compass.groovy 并且放在 classpath 的根目录下。 refresh-check-delay 属性表示每 10 秒钟看看该 script 是否改变了,然后对其进行相应的 update 和 reload 操作。
<lang:jruby> 元素建了一个由 Ruby( 指定为 JRuby) script 实现的 bean ,名字叫 PirateHat.rb 。它实现了 PirateHat 接口并每分钟都会检查是否需要 update 。
XSD:http://www.springframework.org/schema/task/spring-task-3.0.xsd
位置:org/springframework/scheduling/config/spring-task-3.0.xsd
xmlns:task=”http://www.springframework.org/schema/task”
可以部分去取代 quartz,并且支持注解方式。但是如果使用更加复杂的任务调度。还是建议是使用quartz。以下就使用 task 和 quartz来进行任务调度的方法进行距离
package com.alcor.aerie.quartz; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @Service public class TestJob { /** * Logger for this class */ private static final Logger logger = LoggerFactory.getLogger(TestJob.class); @Scheduled(fixedDelay = 1000) public void work() { if (logger.isDebugEnabled()) { logger.debug("work() - start"); //$NON-NLS-1$ } logger.info("Spring Quartz的TestJob任务被调用!"); if (logger.isDebugEnabled()) { logger.debug("work() - end"); //$NON-NLS-1$ } } }
注意其中的@Scheduled 标签
<task:annotation-driven/>
不使用注解,而通过配置来调度任务
<task:scheduled-tasks> <task:scheduled ref="testJob" method="work" cron="1/3 * 2-23 * * ?"/> </task:scheduled-tasks>
分页
XSD:http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
位置:org/springframework/jdbc/config/spring-jdbc-3.0.xsd
xmlns:jdbc=”http://www.springframework.org/schema/jdbc”
XSD:http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
位置:org/springframework/jms/config/spring-jms-3.0.xsd
xmlns:jms=”http://www.springframework.org/schema/jms”
<bean id=”connectionFactory” class=”org.apache.activemq.ActiveMQConnectionFactory”> <property name=”brokerURL” value=”tcp://localhost:61616” /> </bean> <bean id=”messageHandlerService” class=”com.pirate.Message¬HandlerImpl” /> <jms:listener-container connection-factory=”connectionFactory”> <jms:listener destination=”queue.bottle” ref=”messageHandlerService” method=”readMessageFromBottle” /> </jms:listener-container>
<jms:listener-container> 配置了一个容器,专门用于处理到达 JMS connection factory 里的 topics 或 queues 的消息。在这个元素里,你可以声明一个或多个 <jms:listener> 元素,用来响应各自的 topics 。在这个例子中,单独的 <jms:listener> 会在消息到达“ queue.bottle ”这个 topic 时,调用“ messageHandlerService ” bean 的 readMessageFromBottle() 方法。
XSD:http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
位置:org/springframework/oxm/config/spring-oxm-3.0.xsd
xmlns:oxm=”http://www.springframework.org/schema/oxm”
XSD:http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
位置:org/springframework/transaction/config/spring-tx-3.0.xsd
xmlns:tx=”http://www.springframework.org/schema/tx”
<tx:jta-transaction-manager /> <tx:advice id=”txAdvice”> <tx:attributes> <tx:method name=”plunder*” propagation=”REQUIRED” /> <tx:method name=”*” propagation=”SUPPORTS” /> </tx:attributes> </tx:advice> <aop:config> <aop:advisor pointcut=”execution(* ..Pirate.*(..))” advice-ref=”txAdvice” /> </aop:config>
<tx:jta-transaction-manager> 已经加入到 Spring2.5 中用于自动检测由 WebLogic , WebSphere 或 OC4J 提供的 JTA 事务管理。它默认是以叫“ transactionManager ”的 bean 配置在 Spring context 中的。
接下来, <tx:advice> 建立了一个 AOP advice 用于声明事务处理规则。在这个例子中,任何以“ plunder ”为前缀的方法都会得到一个事务。其它方法的规则则是“ support ”事务,并不要求一定会有事务来参与。最后,这个从先前 aop 命令空间借用的例子使用了具备事务性质的 advice 来配置成一个 AOP advistor 。定义在这儿的 pointcut 只对 Pirate 类的所有方法起作用。
Java 事务配置规则
如果你正在考虑压缩 Spring 配置的 XML 数据的话,考虑用 <tx:annotation-driven> 元素试试吧。一旦该元素配置好了,你可以使用开始使用 annotation 来配置你的 beans ,而且只要使用 @Transactional 来定义事务边界和规则即可。你可以看看 Spring In Action 2nd 第六章 6.4.4 节了解更多内容。
XSD:http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
位置:org/springframework/web/servlet/config/spring-mvc-3.0.xsd
xmlns:mvc=”http://www.springframework.org/schema/mvc”