changes for 1.2 M1 release packaging.
This commit is contained in:
62
Spring.build
62
Spring.build
@@ -717,13 +717,8 @@
|
||||
|
||||
<call target="set-debug-build-configuration"/>
|
||||
|
||||
|
||||
<call target="package-release-files"/>
|
||||
<copy todir="${current.package.dir}">
|
||||
<fileset>
|
||||
<include name="Spring.Net.sln"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
|
||||
<property name="project.zip-path" value="${package.dir}/${project.name}-${package.version}.zip"/>
|
||||
<!-- for some reason this isn't being properly excluded in src.to.copy -->
|
||||
@@ -746,8 +741,9 @@
|
||||
<mkdir dir="${current.package.dir}/build-support/tools"/>
|
||||
<copy todir="${current.package.dir}/build-support/tools">
|
||||
<fileset basedir="tools">
|
||||
<include name="**/*.exe"/>
|
||||
<include name="**/*.jar"/>
|
||||
<include name="antlr-2.7.6/*"/>
|
||||
<include name="NAnt.NUnit2OutProc.Task/*"/>
|
||||
<include name="nunit/*"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
@@ -810,13 +806,15 @@
|
||||
<echo message="Current package directory = ${current.package.dir}"/>
|
||||
<copy todir="${current.package.dir}">
|
||||
<fileset>
|
||||
<include name="${solution.file.1.1.2002}"/>
|
||||
<include name="${solution.file.1.1.2003}"/>
|
||||
<include name="${solution.file.1.1.2005}"/>
|
||||
<include name="${solution.file.2002}"/>
|
||||
<include name="${solution.file.2003}"/>
|
||||
<include name="${solution.file.2005}"/>
|
||||
<include name="${solution.file.2008}"/>
|
||||
<include name="readme.txt"/>
|
||||
<include name="changelog.txt"/>
|
||||
<include name="license.txt"/>
|
||||
<include name="BreakingChanges-1.1.txt"/>
|
||||
<include name="Spring.build"/>
|
||||
<include name="Spring.include"/>
|
||||
<!-- exclude VS.Net stuff -->
|
||||
<exclude name="**/sdk-web/**"/>
|
||||
<exclude name="**/*.suo"/>
|
||||
@@ -882,6 +880,10 @@
|
||||
<include name="**/Spring.Messaging.xml"/>
|
||||
<include name="**/Spring.Messaging.pdb"/>
|
||||
|
||||
<include name="**/Spring.Scheduling.Quartz.dll"/>
|
||||
<include name="**/Spring.Scheduling.Quartz.xml"/>
|
||||
<include name="**/Spring.Scheduling.Quartz.pdb"/>
|
||||
|
||||
<include name="**/antlr.runtime.dll"/>
|
||||
<include name="**/Common.Logging.dll"/>
|
||||
<include name="**/Common.Logging.*.dll"/>
|
||||
@@ -960,6 +962,7 @@
|
||||
<include name="**/Rhino.Mocks.dll"/>
|
||||
<include name="**/System.Web.Extensions.dll"/>
|
||||
<include name="**/Apache.NMS.dll"/>
|
||||
<include name="**/Apache.NMS.ActiveMQ.dll"/>
|
||||
<include name="**/Apache.NMS.MSMQ.dll"/>
|
||||
<include name="**/EULA.rtf"/>
|
||||
</fileset>
|
||||
@@ -987,6 +990,17 @@
|
||||
</if>
|
||||
|
||||
|
||||
<mkdir dir="${current.package.dir}/lib/NHibernate20"/>
|
||||
<if test="${property::exists('build.allnamespaces') and not build.allnamespaces}">
|
||||
<copy todir="${current.package.dir}/lib/NHibernate20">
|
||||
<fileset basedir="lib/NHibernate20">
|
||||
<include name="**/*.dll"/>
|
||||
<include name="**/*.license.txt"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</if>
|
||||
|
||||
|
||||
<if test="${property::exists('build.allnamespaces') and build.allnamespaces}">
|
||||
<copy todir="${current.package.dir}/lib">
|
||||
<fileset basedir="lib">
|
||||
@@ -997,14 +1011,22 @@
|
||||
</if>
|
||||
|
||||
<!-- copy third-party icons -->
|
||||
<mkdir dir="${current.package.dir}/icons"/>
|
||||
<copy todir="${current.package.dir}/icons">
|
||||
<fileset basedir="icons">
|
||||
<mkdir dir="${current.package.dir}/build-support/icons"/>
|
||||
<copy todir="${current.package.dir}/build-support/icons">
|
||||
<fileset basedir="build-support/icons">
|
||||
<include name="*.ico"/>
|
||||
<include name="*.pal"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- copy additional convenience solution files -->
|
||||
<mkdir dir="${current.package.dir}/build-support/solutions"/>
|
||||
<copy todir="${current.package.dir}/build-support/solutions">
|
||||
<fileset basedir="build-support/solutions">
|
||||
<include name="*.sln"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- copy schema and dtd -->
|
||||
<mkdir dir="${current.package.dir}/doc/schema"/>
|
||||
<copy todir="${current.package.dir}/doc/schema"
|
||||
@@ -1187,9 +1209,10 @@
|
||||
<property name="build-winservices" value="true"/>
|
||||
<property name="build-web" value="true"/>
|
||||
<property name="build-examples" value="true"/>
|
||||
<property name="solution.file.1.1.2002" value="Spring.Net.1.1.2002.sln"/>
|
||||
<property name="solution.file.1.1.2003" value="Spring.Net.1.1.2003.sln"/>
|
||||
<property name="solution.file.1.1.2005" value="Spring.Net.1.1.2005.sln"/>
|
||||
<property name="solution.file.2002" value="Spring.Net.2002.sln"/>
|
||||
<property name="solution.file.2003" value="Spring.Net.2003.sln"/>
|
||||
<property name="solution.file.2005" value="Spring.Net.2005.sln"/>
|
||||
<property name="solution.file.2008" value="Spring.Net.2008.sln"/>
|
||||
<fileset id="src.to.copy">
|
||||
<include name="src/Spring/Spring.Core/**"/>
|
||||
<include name="src/Spring/Spring.Aop/**"/>
|
||||
@@ -1200,11 +1223,13 @@
|
||||
<include name="src/Spring/Spring.Services/Web/**"/>
|
||||
<include name="src/Spring/Spring.Services/Spring.Services.2003.csproj"/>
|
||||
<include name="src/Spring/Spring.Services/Spring.Services.2005.csproj"/>
|
||||
<include name="src/Spring/Spring.Services/Spring.Services.2008.csproj"/>
|
||||
<include name="src/Spring/Spring.Services/*.build"/>
|
||||
<include name="src/Spring/Spring.Services/AssemblyInfo.cs"/>
|
||||
<include name="src/Spring/Spring.Data/**"/>
|
||||
<include name="src/Spring/Spring.Data.NHibernate/**"/>
|
||||
<include name="src/Spring/Spring.Data.NHibernate12/**"/>
|
||||
<include name="src/Spring/Spring.Data.NHibernate20/**"/>
|
||||
<include name="src/Spring/Spring.Testing.NUnit/**"/>
|
||||
<include name="src/Spring/CommonAssemblyInfo.cs"/>
|
||||
|
||||
@@ -1217,6 +1242,7 @@
|
||||
<include name="test/Spring/Spring.Services.Tests/Web/**"/>
|
||||
<include name="test/Spring/Spring.Services.Tests/Spring.Services.Tests.2003.csproj"/>
|
||||
<include name="test/Spring/Spring.Services.Tests/Spring.Services.Tests.2005.csproj"/>
|
||||
<include name="test/Spring/Spring.Services.Tests/Spring.Services.Tests.2008.csproj"/>
|
||||
<include name="test/Spring/Spring.Services.Tests/Spring.Services.Tests.build"/>
|
||||
<include name="test/Spring/Spring.Services.Tests/*.config"/>
|
||||
<include name="test/Spring/Spring.Services.Tests/Spring.Services.Tests.dll.config"/>
|
||||
|
||||
BIN
build-support/icons/spring.ico
Normal file
BIN
build-support/icons/spring.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
build-support/icons/spring.pal
Normal file
BIN
build-support/icons/spring.pal
Normal file
Binary file not shown.
BIN
build-support/icons/spring16.ico
Normal file
BIN
build-support/icons/spring16.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
build-support/icons/spring32-16.ico
Normal file
BIN
build-support/icons/spring32-16.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
build-support/icons/spring32.ico
Normal file
BIN
build-support/icons/spring32.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,420 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Check Application Requirements
|
||||
Check/Install Application Pre-Requisites
|
||||
Check Application Pre-Requisites
|
||||
Install Application Pre-Requisites
|
||||
Define Setup Globals
|
||||
Setup User Interview
|
||||
Perform Uninstallation
|
||||
Finish Setup
|
||||
@@ -0,0 +1,504 @@
|
||||
Spring.NET-1.2.mia
|
||||
componentstree.dfm
|
||||
componentstree.dfm.miaf
|
||||
destination.dfm
|
||||
destination.dfm.miaf
|
||||
finish.dfm
|
||||
finish.dfm.miaf
|
||||
licensecheck.dfm
|
||||
licensecheck.dfm.miaf
|
||||
maintenance.dfm
|
||||
maintenance.dfm.miaf
|
||||
prereq.dfm
|
||||
prereq.dfm.miaf
|
||||
progress.dfm
|
||||
progress.dfm.miaf
|
||||
progressprereq.dfm
|
||||
progressprereq.dfm.miaf
|
||||
readme.dfm
|
||||
readme.dfm.miaf
|
||||
registration.dfm
|
||||
registration.dfm.miaf
|
||||
registrationwithserial.dfm
|
||||
registrationwithserial.dfm.miaf
|
||||
setuptype.dfm
|
||||
setuptype.dfm.miaf
|
||||
startinstallation.dfm
|
||||
startinstallation.dfm.miaf
|
||||
startmenu.dfm
|
||||
startmenu.dfm.miaf
|
||||
welcome.dfm
|
||||
welcome.dfm.miaf
|
||||
wizard.dfm
|
||||
wizard.dfm.miaf
|
||||
$
|
||||
icon.ico
|
||||
$
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$
|
||||
$
|
||||
1
|
||||
0
|
||||
FALSE
|
||||
L:\projects\spring-net\msi
|
||||
SpringSource
|
||||
Spring.NET 1.2 M1
|
||||
{36A8EE3D-7025-4FAE-BF84-0523EADA7082}
|
||||
{1399F2CB-026A-4995-ADC7-9A921EEFB4E9}
|
||||
1.2
|
||||
English
|
||||
Spring.NET 1.2 M1
|
||||
Spring.NET 1.2 M1
|
||||
Spring.NET authors
|
||||
All rights reserved
|
||||
{3A73E939-3C01-4C93-8CAB-39C3C40CFC05}
|
||||
Spring.NET
|
||||
Spring.NET
|
||||
http://forum.springframework.net
|
||||
http://www.springframework.net
|
||||
All rights reserved
|
||||
FALSE
|
||||
Spring.NET-1.2-M1
|
||||
TRUE
|
||||
FALSE
|
||||
|
||||
|
||||
http://timestamp.verisign.com/scripts/timstamp.dll
|
||||
|
||||
|
||||
$
|
||||
$
|
||||
|
||||
|
||||
Service Pack
|
||||
FALSE
|
||||
FALSE
|
||||
FALSE
|
||||
TRUE
|
||||
TRUE
|
||||
FALSE
|
||||
FALSE
|
||||
FALSE
|
||||
|
||||
$
|
||||
FALSE
|
||||
|
||||
@@ -0,0 +1,504 @@
|
||||
Spring.NET-1.2.mia
|
||||
componentstree.dfm
|
||||
componentstree.dfm.miaf
|
||||
destination.dfm
|
||||
destination.dfm.miaf
|
||||
finish.dfm
|
||||
finish.dfm.miaf
|
||||
licensecheck.dfm
|
||||
licensecheck.dfm.miaf
|
||||
maintenance.dfm
|
||||
maintenance.dfm.miaf
|
||||
prereq.dfm
|
||||
prereq.dfm.miaf
|
||||
progress.dfm
|
||||
progress.dfm.miaf
|
||||
progressprereq.dfm
|
||||
progressprereq.dfm.miaf
|
||||
readme.dfm
|
||||
readme.dfm.miaf
|
||||
registration.dfm
|
||||
registration.dfm.miaf
|
||||
registrationwithserial.dfm
|
||||
registrationwithserial.dfm.miaf
|
||||
setuptype.dfm
|
||||
setuptype.dfm.miaf
|
||||
startinstallation.dfm
|
||||
startinstallation.dfm.miaf
|
||||
startmenu.dfm
|
||||
startmenu.dfm.miaf
|
||||
welcome.dfm
|
||||
welcome.dfm.miaf
|
||||
wizard.dfm
|
||||
wizard.dfm.miaf
|
||||
$
|
||||
icon.ico
|
||||
$
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$
|
||||
$
|
||||
1
|
||||
0
|
||||
FALSE
|
||||
L:\projects\spring-net\msi
|
||||
SpringSource
|
||||
Spring.NET 1.2 M1
|
||||
{36A8EE3D-7025-4FAE-BF84-0523EADA7082}
|
||||
{1399F2CB-026A-4995-ADC7-9A921EEFB4E9}
|
||||
1.2
|
||||
English
|
||||
Spring.NET 1.2 M1
|
||||
Spring.NET 1.2 M1
|
||||
Spring.NET authors
|
||||
All rights reserved
|
||||
{CA310973-F1EA-49C3-B9B0-2071DAB16AF8}
|
||||
Spring.NET
|
||||
Spring.NET
|
||||
http://forum.springframework.net
|
||||
http://www.springframework.net
|
||||
All rights reserved
|
||||
FALSE
|
||||
Spring.NET-1.2-M1
|
||||
TRUE
|
||||
FALSE
|
||||
|
||||
|
||||
http://timestamp.verisign.com/scripts/timstamp.dll
|
||||
|
||||
|
||||
$
|
||||
$
|
||||
|
||||
|
||||
Service Pack
|
||||
FALSE
|
||||
FALSE
|
||||
FALSE
|
||||
TRUE
|
||||
TRUE
|
||||
FALSE
|
||||
FALSE
|
||||
FALSE
|
||||
|
||||
$
|
||||
FALSE
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
build-support/installer/installaware/Spring.NET-1.2/finish.dfm
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/finish.dfm
Normal file
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
IF (checkSuccess.Caption = COMPLETE) THEN textComplete.Visible := True;
|
||||
IF (checkSuccess.Caption = REBOOT) THEN textReboot.Visible := True;
|
||||
IF (checkSuccess.Caption = CANCEL) THEN textCancelled.Visible := True;
|
||||
IF (checkSuccess.Caption = ERROR) THEN textError.Visible := True;
|
||||
IF (checkRemove.Caption = TRUE) THEN textRemove.Visible := True;
|
||||
IF (checkSuccess.Caption <> COMPLETE) THEN textComplete.Visible := False;
|
||||
IF (checkSuccess.Caption <> REBOOT) THEN textReboot.Visible := False;
|
||||
IF (checkSuccess.Caption <> CANCEL) THEN textCancelled.Visible := False;
|
||||
IF (checkSuccess.Caption <> ERROR) THEN textError.Visible := False;
|
||||
IF (checkRemove.Caption <> TRUE) THEN textRemove.Visible := False;
|
||||
IF (checkRemove.Caption = TRUE) THEN textComplete.Visible := False;
|
||||
IF (checkSuccess.Caption = CANCEL) THEN textRemove.Visible := False;
|
||||
IF (textReboot.Visible = True) THEN textRemove.Visible := false;
|
||||
IF (textComplete.Visible = True) THEN textRemove.Visible := false;
|
||||
IF (textError.Visible = True) THEN textRemove.Visible := false;
|
||||
IF (textCancelled.Visible = True) THEN textRemove.Visible := false;
|
||||
IF (checkSuccess.Caption = ERROR) THEN textRemove.Visible := False;
|
||||
BIN
build-support/installer/installaware/Spring.NET-1.2/icon.ico
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
IF (LicenseCheck.Checked = True) THEN Next.Enabled := True;
|
||||
IF (LicenseCheck.Checked = False) THEN Next.Enabled := False;
|
||||
BIN
build-support/installer/installaware/Spring.NET-1.2/mMSIExec.dll
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/mMSIExec.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
build-support/installer/installaware/Spring.NET-1.2/prereq.dfm
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/prereq.dfm
Normal file
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
IF (checkWINST.Caption <> TRUE) THEN WINST.Visible := True;
|
||||
IF (checkJS.Caption <> TRUE) THEN JS.Visible := True;
|
||||
IF (checkDotNET.Caption <> TRUE) THEN dotNET.Visible := True;
|
||||
IF (checkWINST.Caption = TRUE) THEN WINST.Visible := False;
|
||||
IF (checkDotNET.Caption = TRUE) THEN dotNET.Visible := False;
|
||||
IF (checkJS.Caption = TRUE) THEN JS.Visible := False;
|
||||
BIN
build-support/installer/installaware/Spring.NET-1.2/progress.dfm
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/progress.dfm
Normal file
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
IF (TestRemove.Caption <> TRUE) THEN CaptionInstall.Visible := True;
|
||||
IF (TestRemove.Caption = TRUE) THEN CaptionUninstall.Visible := True;
|
||||
IF (TestRemove.Caption <> TRUE) THEN CaptionUninstall.Visible := False;
|
||||
IF (TestRemove.Caption = TRUE) THEN CaptionInstall.Visible := False;
|
||||
Binary file not shown.
BIN
build-support/installer/installaware/Spring.NET-1.2/readme.dfm
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/readme.dfm
Normal file
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
IF (LicenseCheck.Checked = True) THEN Next.Enabled := True;
|
||||
IF (LicenseCheck.Checked = False) THEN Next.Enabled := False;
|
||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
IF (Name.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Company.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Name.Text = ) THEN Next.Enabled := False;
|
||||
IF (Company.Text = ) THEN Next.Enabled := False;
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
IF (Name.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Company.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Serial1.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Serial2.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Serial3.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Serial4.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Serial5.Text <> ) THEN Next.Enabled := True;
|
||||
IF (Name.Text = ) THEN Next.Enabled := False;
|
||||
IF (Company.Text = ) THEN Next.Enabled := False;
|
||||
IF (Serial1.Text = ) THEN Next.Enabled := False;
|
||||
IF (Serial2.Text = ) THEN Next.Enabled := False;
|
||||
IF (Serial3.Text = ) THEN Next.Enabled := False;
|
||||
IF (Serial4.Text = ) THEN Next.Enabled := False;
|
||||
IF (Serial5.Text = ) THEN Next.Enabled := False;
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
IF (MenuGroup.Text <> ) THEN Next.Enabled := True;
|
||||
IF (MenuGroup.Text = ) THEN Next.Enabled := False;
|
||||
IF (ISNT.Caption = TRUE) THEN AllUsers.Enabled := True;
|
||||
IF (ISNT.Caption <> TRUE) THEN AllUsers.Enabled := False;
|
||||
BIN
build-support/installer/installaware/Spring.NET-1.2/welcome.dfm
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/welcome.dfm
Normal file
Binary file not shown.
BIN
build-support/installer/installaware/Spring.NET-1.2/wizard.dfm
Normal file
BIN
build-support/installer/installaware/Spring.NET-1.2/wizard.dfm
Normal file
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
nunit-console-*
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
<!ENTITY overview SYSTEM "overview.xml">
|
||||
<!ENTITY psa-intro SYSTEM "psa-intro.xml">
|
||||
<!ENTITY remoting SYSTEM "remoting.xml">
|
||||
<!ENTITY nms SYSTEM "nms.xml">
|
||||
<!ENTITY messaging SYSTEM "messaging.xml">
|
||||
<!ENTITY msmq SYSTEM "msmq.xml">
|
||||
<!ENTITY scheduling SYSTEM "scheduling.xml">
|
||||
<!ENTITY web SYSTEM "web.xml">
|
||||
<!ENTITY ajax SYSTEM "ajax.xml">
|
||||
<!ENTITY services SYSTEM "services.xml">
|
||||
@@ -300,23 +301,19 @@
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><xref linkend="nms"/></para>
|
||||
<para><xref linkend="messaging"/></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><xref linkend="msmq"/></para>
|
||||
</listitem>
|
||||
<!--
|
||||
<listitem>
|
||||
<para><xref linkend="scheduling"/></para>
|
||||
</listitem>
|
||||
-->
|
||||
</itemizedlist>
|
||||
</partintro>
|
||||
&nms;
|
||||
&messaging;
|
||||
&msmq;
|
||||
<!--
|
||||
&scheduling;
|
||||
-->
|
||||
</part>
|
||||
|
||||
<part id="index-vsnet">
|
||||
|
||||
745
doc/reference/src/messaging.xml
Normal file
745
doc/reference/src/messaging.xml
Normal file
@@ -0,0 +1,745 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter id="messaging">
|
||||
<title>Message Oriented Middleware</title>
|
||||
|
||||
<section>
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>The goal of Spring's messaging is to increase your productiviity
|
||||
when writing an enterprise strength messaging middleware applications.
|
||||
Spring achieves these goals in several ways. First it provides several
|
||||
helper classes that remove from the developer the incidental complexity
|
||||
and resource management issues that arrise when using messaging APIs. In
|
||||
particular, this chapter deals with messaging providers whose API is done
|
||||
in the spirit of the Java Message Service (JMS) API. Vendors who provide a
|
||||
JMS inspired API include TIBCO, IBM, and Sonic Software. (If you are using
|
||||
Microsoft's Message Queue, please refer to the specific <link
|
||||
linkend="msmq">MSMQ section</link>). Second, the design of these messaging
|
||||
helper classes promote best practices in desigining a messaging
|
||||
applicaiton by promoting a clear separation between the messaging
|
||||
middleware specific code and business processing that is technology
|
||||
agnostic. This is generally referred to a "plain old .NET object" (or
|
||||
PONO) programming model. Lastly, as there is no defacto-standard common
|
||||
API across messaging vendors, Spring provides an implementation for each
|
||||
of the major messaging middleware vendors. Portability across each vendor
|
||||
is promoted by providing a configuration schema that hides the actual
|
||||
class types used for Spring's helper class as well as consistent naming of
|
||||
the helper classes in different namespaces. The goal with vendor
|
||||
portability is to get as far as possible by simply changing your 'using'
|
||||
statements in code and schema name in the configuration. </para>
|
||||
|
||||
<para>JMS can be roughly divided into two areas of functionality, namely
|
||||
the production and consumption of messages. The
|
||||
<classname>MessageTemplate</classname> class is used for message
|
||||
production and synchronous message reception. For asynchronous reception,
|
||||
Spring provides a multi-threaded message listener container,
|
||||
<classname>SimpleMessageListenerContainer</classname>, that can be sued to
|
||||
to create Message-Driven PONOs (MDPs). The MessageConverter interface is
|
||||
used by both the MessageTemplate class and the message listener container
|
||||
to converte between provider message types and PONOs.</para>
|
||||
|
||||
<para>For each vendor there is a namespace of the type,
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Core</literal>. For
|
||||
example, in the case of ActiveMQ, you would use
|
||||
<literal>Spring.Messaging.Nms.Core</literal>, for TIBCO you would use
|
||||
<literal>Spring.Messaging.Ems.Core</literal>. This namespace provides the
|
||||
core functionality for messaging. It contains the
|
||||
<literal>MessageTemplate</literal> class that simplifies the use of the
|
||||
messaging APIs by handling the creation and release of resources, much
|
||||
like the AdoTemplate does for ADO.NET. The design principle common to
|
||||
Spring template classes is to provide helper methods to perform common
|
||||
operations and for more sophisticated usage, delegate the essence of the
|
||||
processing task to user implemented callback interfaces. The messaging
|
||||
template follows the same design. The classes offer various convenience
|
||||
methods for the sending of messages, consuming a message synchronously,
|
||||
and exposing the message Session and MessageProducer to the user.</para>
|
||||
|
||||
<para>The namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Support.Converter</literal>
|
||||
provides a <literal>MessageConverter</literal> abstraction to convert
|
||||
between .NET objects and messages. The namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Support.Destinations</literal>
|
||||
provides various strategies for managing destinations, such as providing a
|
||||
service locator for destinations stored in a directory service.</para>
|
||||
|
||||
<para>Finally, the namespace
|
||||
<literal>Spring.Messaging.<VendorAcronym>.Connections</literal>
|
||||
provides an implementations of the ConnectionFactory suitable for use in
|
||||
standalone applications. </para>
|
||||
|
||||
<para>This chapter starts with a 'Quick tour for the impatient' that shows
|
||||
you how to get up and running quickly using Spring's message helper
|
||||
classes. You can also refer to the sample application that ships with
|
||||
Spring for additional hands-on usage. The rest of the sections in this
|
||||
chapter discusses each of the major helper classes in detail. </para>
|
||||
|
||||
<section>
|
||||
<title>Separation of Concerns</title>
|
||||
|
||||
<para>The use of MessageConverters and a PONO programming model promote
|
||||
messaging best practices by applying the principal of Separation of
|
||||
Concerns to messaging based architectures. The infrasructure concern of
|
||||
publishing and consuming messages is separated from the concern of
|
||||
business processing. These two concerns are reflected in the
|
||||
architecture as two distinct layers, a message processing layer and a
|
||||
business processing layer. The benefit of this approach is that your
|
||||
business processing is decoupled from the technology, making it more
|
||||
likely to survive technological changes over time. Spring's
|
||||
MessageConverters provide first class support for mapping messaging data
|
||||
types to PONOs. Aside from being the link between the two layers, having
|
||||
a pluggable strategy for message conversion helps support a loosely
|
||||
coupled architecture over time. Message formats will change over time,
|
||||
typically by the addition of new fields. MessageConverters can detect
|
||||
different versions of messages and perform the appropriate mapping logic
|
||||
to PONOs such so that multiple versions of a message can be supported
|
||||
simultaneously, a common requirement in enterprise messaging
|
||||
architectures. In can loosely associate Spring's MessageConverters to
|
||||
XML/Object mappers but with a messaging twist.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Interopability</title>
|
||||
|
||||
<para>Messaging is a traditional area of interopabiltity across
|
||||
heterogenous systems with messaging vendors providing support on
|
||||
multiple operating systems (Windows, UNIX, Mainframes OS's) as well as
|
||||
multiple language bindings (C, C++, Java, .NET, Perl, etc.). In 199x the
|
||||
Java Community Process came up with a specifcation to provide a common
|
||||
API across messaing providers as well as define some common messaging
|
||||
functionality. This specification is know as the Java Message Service.
|
||||
From the API perspective, it can roughly be thought of as the messaging
|
||||
counterpart to the ADO.NET or JDBC APIs that provide portability across
|
||||
different database providers. Given this history, when messaging vendors
|
||||
created their .NET APIs, many did so by creating their own JMS inspired
|
||||
API in .NET. The NMS project's goal is to provide a common API for .NET
|
||||
thereby giving portability to the various .NET messaging providers. One
|
||||
downside of the NMS API is that it is a low-level API, much like ADO.NET
|
||||
and JDBC. Even the simplist of operations requires 10s of lines of code
|
||||
with the bulk of that code related to resource management of
|
||||
intermediate API objects. Note that the 'core' of the JMS/NMS API is
|
||||
much simplier than with ADO.NET/JDBC. So while NMS provides portability
|
||||
it also brings with it this API 'noise'. Spring's messaging support,
|
||||
both in Java and .NET, addresses the error-prone boiler plate coding
|
||||
style one needs when using thtese APIs.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>The role of Messaging API in a 'WCF world'</title>
|
||||
|
||||
<para>Windows Communication Foundation (WCF) also supports message
|
||||
oriented middleware. Not surprisingly, a Microsoft Message Queuing
|
||||
(MSMQ) binding is provided as part of WCF. The WCF programming model is
|
||||
higher level than the traditional messaging APIs such as JMS and NMS
|
||||
since you are programing to a sevice interface and use metadata (either
|
||||
XML or attributes) to configure the messaging behavior. This is a big
|
||||
improvement over using low-level vendor specific APIs. However, at the
|
||||
time of this writing, it is not clear that other messaging providers
|
||||
will provide WCF bindings. A Spring Extensions project, Spring-NMS,
|
||||
provides a WCF binding for NMS. This will let you use the WCF
|
||||
programming model but still retain portability across messaging
|
||||
providers.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Using Spring JMS</title>
|
||||
|
||||
<section>
|
||||
<title>JmsTemplate</title>
|
||||
|
||||
<para>Code that uses the JmsTemplate only needs to implement callback
|
||||
interfaces giving them a clearly defined contract. The IMessageCreator
|
||||
callback interface creates a message given a Session provided by the
|
||||
calling code in JmsTemplate. In order to allow for more complex usage of
|
||||
the JMS API, the callback ISessionCallback provides the user with the
|
||||
JMS session and the callback IProducerCallback exposes a Session and
|
||||
MessageProducer pair.</para>
|
||||
|
||||
<para>The JMS API exposes two types of send methods, one that takes
|
||||
delivery mode, priority, and time-to-live as quality of service (QOS)
|
||||
parameters and one that takes no QOS parameters which uses default
|
||||
values. Since there are many send methods in JmsTemplate, the setting of
|
||||
the QOS parameters have been exposed as bean properties to avoid
|
||||
duplication in the number of send methods. Similarly, the timeout value
|
||||
for synchronous receive calls is set using the property
|
||||
ReceiveTimeout.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Connections</title>
|
||||
|
||||
<para>The JmsTemplate requires a reference to a ConnectionFactory. The
|
||||
ConnectionFactory is part of the JMS specification and serves as the
|
||||
entry point for working with JMS. It is used by the client application
|
||||
as a factory to create connections with the JMS provider and
|
||||
encapsulates various configuration parameters, many of which are vendor
|
||||
specific such as SSL configuration options.</para>
|
||||
|
||||
<para>Note: The TIBCO implementation is not interface based and its
|
||||
methods are not virtual so no additional functionality that may
|
||||
otherewise be part of a ConnectionFactory 'Wrapper' are provided. This
|
||||
type of functionality wil be available when Spring.NET uses the
|
||||
implementation neutral NMS AP(s.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Destination Management</title>
|
||||
|
||||
<para>In Java implementations of JMS, Connections and Destinations are
|
||||
'administered objects' accessible though JNDI. In .NET each vendor has
|
||||
selected a different approach, generally JNDI inspired, to retrieve
|
||||
Connections and Destinations that were configured administratively. You
|
||||
can use these vendor specific APIs to perform dependency injection on
|
||||
references to JMS Destination objects in Sprng's XML configuration file
|
||||
by creating am implementation of IObjectFactory.</para>
|
||||
|
||||
<para>However, this approach of administerd objects can be quite
|
||||
cumbersome if there are a large number of destinations in the
|
||||
application or if there are advanced destination management features
|
||||
unique to the JMS provider. Examples of such advanced destination
|
||||
management would be the creation of dynamic destinations or support for
|
||||
a hierarchical namespace of destinations. The JmsTemplate delegates the
|
||||
resolution of a destination name to a JMS destination object to an
|
||||
implementation of the interface IDestinationResolver.
|
||||
DynamicDestinationResolver is the default implementation used by
|
||||
JmsTemplate and accommodates resolving dynamic destinations. A
|
||||
JndiDestinationResolver is also provided that acts as a service locator
|
||||
for destinations contained in JNDI and optionally falls back to the
|
||||
behavior contained in DynamicDestinationResolver.</para>
|
||||
|
||||
<para>Quite often the destinations used in a JMS application are only
|
||||
known at runtime and therefore cannot be administratively created when
|
||||
the application is deployed. This is often because there is shared
|
||||
application logic between interacting system components that create
|
||||
destinations at runtime according to a well-known naming convention.
|
||||
Even though the creation of dynamic destinations are not part of the JMS
|
||||
specification, most vendors have provided this functionality. Dynamic
|
||||
destinations are created with a name defined by the user which
|
||||
differentiates them from temporary destinations and are often not
|
||||
registered in a JNDI-like directory.. The API used to create dynamic
|
||||
destinations varies from provider to provider since the properties
|
||||
associated with the destination are vendor specific. However, a simple
|
||||
implementation choice that is sometimes made by vendors is to disregard
|
||||
the warnings in the JMS specification and to use the TopicSession method
|
||||
createTopic(String topicName) or the QueueSession method
|
||||
createQueue(String queueName) to create a new destination with default
|
||||
destination properties. Depending on the vendor implementation,
|
||||
DynamicDestinationResolver may then also create a physical destination
|
||||
instead of only resolving one.</para>
|
||||
|
||||
<para>The boolean property PubSubDomain determines the behavior of
|
||||
dynamic destination resolution via implementations of the
|
||||
DestinationResolver interface.</para>
|
||||
|
||||
<para>You can also configure the JmsTemplate with a default destination
|
||||
via the property defaultDestination. The default destination will be
|
||||
used with send and receive operations that do not refer to a specific
|
||||
destination.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Message Listener Containers</title>
|
||||
|
||||
<para>One of the most common uses of JMS is to concurrently process
|
||||
messages delivered asynchronously.</para>
|
||||
|
||||
<para>A subclass of
|
||||
<classname>AbstractMessageListenerContainer</classname> is used to
|
||||
receive messages from JMS and drive the Message-Driven POCOs (MDPs) that
|
||||
are injected into it. The
|
||||
<classname>AbstractMessageListenerContainer</classname> is responsible
|
||||
for all threading of message reception and dispatch into the MDPs for
|
||||
processing. A message listener container is the intermediary between an
|
||||
MDP and a messaging provider, and takes care of registering to receive
|
||||
messages, participating in transactions, resource acquisition and
|
||||
release, exception conversion and suchlike. This allows you as an
|
||||
application developer to write the (posssibly complex) business logic
|
||||
associated with receiving a message (and possibly responding to it), and
|
||||
delegates boilerplate JMS infrastructure concerns to the framework.
|
||||
There are one subclasses of
|
||||
<classname>AbstractMessageListenerContainer</classname> packaged with
|
||||
Spring - <classname>SimpleMessageListenerContainer</classname>.</para>
|
||||
|
||||
<para>SimpleMessageListenerContainer creates a fixed number of JMS
|
||||
sessions at startup and uses them throughout the lifespan of the
|
||||
container. This subclass doesn't allow for dynamic adaption to runtime
|
||||
demands or participate in transactional reception of messages.</para>
|
||||
|
||||
<para>Spring.Java provides two other subclasses, one to support
|
||||
distributed transactions and the other to provide a dynamic session
|
||||
management to optimize concurrent processing. Distributed transaction
|
||||
support is not provided by .NET C# vendors (AFAIK) and neither is the
|
||||
dynamic session management support which is based on the
|
||||
ServerSessionPool SPI - an optional part of the JMS
|
||||
specification.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Transaction Management</title>
|
||||
|
||||
<para>TBD. This relates to integration with Spring's transaction
|
||||
management features, the ability to have transacted JMS sessions is
|
||||
supported.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Sending a Message</title>
|
||||
|
||||
<para>The <classname>JmsTemplate</classname> contains three convenience
|
||||
methods to send a message. The methods are listed below.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>void Send(Destination destination, IMessageCreator
|
||||
messageCreator)</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>void Send(string destinationName, IMessageCreator
|
||||
messageCreator)</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>void Send(IMessageCreator
|
||||
messageCreator)</literal></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Which differ in how the destination is specified. In first case the
|
||||
JMS Destination object is specified directly. The second case specifies
|
||||
the destination using a string that is then resolved to a JMS JMS
|
||||
<classname>Destination</classname> object using the DestinationResolver
|
||||
associated with the template. The last method sends the message to the
|
||||
destination specified by JmsTemplates
|
||||
<classname>DefaultDestination</classname> property.</para>
|
||||
|
||||
<para>All methods take as an argument an instance of IMessageCreator which
|
||||
defines the API contract for you to create the JMS message. The interface
|
||||
is show below</para>
|
||||
|
||||
<para><programlisting>public interface IMessageCreator {
|
||||
Message CreateMessage(Session session);
|
||||
}</programlisting>Intermediate JMS Sessions and MessageProducers needed to
|
||||
send the message are managed by JmsTemplate. The session passed in to the
|
||||
method is never null. There is a similar set methods that use a delegate
|
||||
instead of the interface, which can be convenientwhen writing small
|
||||
implementaitons in .NET 2.0 using anonymous delegates. Larger, more
|
||||
complex implementations of the method 'CreateMessage' are better suited to
|
||||
an interface based implementation.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>void SendWithDelegate(Destination destination,
|
||||
MessageCreatorDelegate messageCreatorDelegate)</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>void SendWithDelegate(string destinationName,
|
||||
MessageCreatorDelegate messageCreatorDelegate)</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>void SendWithDelegate(MessageCreatorDelegate
|
||||
messageCreatorDelegate)</literal></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The declaration of the delegate is</para>
|
||||
|
||||
<programlisting>public delegate Message MessageCreatorDelegate(Session session);</programlisting>
|
||||
|
||||
<para>The following class shows how to use the API with an anonymous
|
||||
delegate, making for very terse syntax and easy access to local variables.
|
||||
A more realistic example would create the JmsTemplate via dependency
|
||||
injection, allowing for easy configuration of the connection string. A
|
||||
convenience class, JmsGatewaySupport, already contains a property of type
|
||||
JmsTemplate for you to use in</para>
|
||||
|
||||
<programlisting> public class SimplePublisher
|
||||
{
|
||||
private JmsTemplate template;
|
||||
|
||||
public SimplePublisher()
|
||||
{
|
||||
template = new JmsTemplate(new ConnectionFactory("tcp://localhost:7222"));
|
||||
template.PubSubDomain = true;
|
||||
}
|
||||
|
||||
public void Publish(string ticker, double price)
|
||||
{
|
||||
template.SendWithDelegate("APP.STOCK",
|
||||
delegate(Session session)
|
||||
{
|
||||
MapMessage message = session.CreateMapMessage();
|
||||
message.SetString("TICKER", ticker);
|
||||
message.SetDouble("PRICE", price);
|
||||
message.Priority = 2;
|
||||
return message;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</programlisting>
|
||||
|
||||
<section>
|
||||
<title>Using MessageConverters</title>
|
||||
|
||||
<para>In order to facilitate the sending of domain model objects, the
|
||||
<classname>JmsTemplate</classname> has various send methods that take a
|
||||
.NET object as an argument for a message's data content. The overloaded
|
||||
methods ConvertAndSend and ReceiveAndConvert in
|
||||
<classname>JmsTemplate</classname> delegate the conversion process to an
|
||||
instance of the <interfacename>MessageConverter</interfacename>
|
||||
interface. This interface defines a simple contract to convert between
|
||||
.NET objects and JMS messages. The default implementation
|
||||
<classname>SimpleMessageConverter</classname> supports conversion
|
||||
between String and TextMessage, byte[] and BytesMesssage, and
|
||||
System.Collections.IDictionary and MapMessage. By using the converter,
|
||||
you and your application code can focus on the business object that is
|
||||
being sent or received via JMS and not be concerned with the details of
|
||||
how it is represented as a JMS message.</para>
|
||||
|
||||
<para>The family of ConvertAndSend messages are similar to that of the
|
||||
Send method with the additional argument of type IMessagePostProcessor.
|
||||
These methods are listed below.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>void ConvertAndSend(object message)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>void ConvertAndSend(object message,
|
||||
IMessagePostProcessor postProcessor)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>void ConvertAndSend(string destinationName, object
|
||||
message)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>void ConvertAndSend(string destinationName, object
|
||||
message, IMessagePostProcessor postProcessor);</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>void ConvertAndSend(Destination destination, object
|
||||
message)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>void ConvertAndSend(Destination destination, object
|
||||
message, IMessagePostProcessor postProcessor)</code></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>In the previous example the message priority was set inside the
|
||||
callback. Generally speaking, converters should not be responsible for
|
||||
setting Quality of Service parameters since they are not aware of the
|
||||
context in which they are being called. The following code show this in
|
||||
action.</para>
|
||||
|
||||
<para><programlisting>public void PublishUsingDict(string ticker, double price)
|
||||
{
|
||||
IDictionary marketData = new Hashtable();
|
||||
marketData.Add("TICKER", ticker);
|
||||
marketData.Add("PRICE", price);
|
||||
template.ConvertAndSend("APP.STOCK", marketData);
|
||||
}</programlisting>A reflection based converter that can converter arbitrary
|
||||
objects is available as a seperate project.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Session and Producer Callback</title>
|
||||
|
||||
<para>While the send operations cover many common usage scenarios, there
|
||||
are cases when you want to perform multiple operations on a JMS Session or
|
||||
MessageProducer. The SessionCallback and ProducerCallback expose the JMS
|
||||
Session and Session / MessageProducer pair respectfully. The Execute()
|
||||
methods on JmsTemplate execute these callback methods.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>public object Execute(IProducerCallback
|
||||
action)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public object Execute(ISessionCallback
|
||||
action)</code></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Where ISessionCallback and IProducerCallback are</para>
|
||||
|
||||
<para><programlisting>public interface IProducerCallback
|
||||
{
|
||||
object DoInJms(Session session, MessageProducer producer);
|
||||
}</programlisting>and</para>
|
||||
|
||||
<programlisting>public interface ISessionCallback
|
||||
{
|
||||
object DoInJms(Session session);
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Receiving a message</title>
|
||||
|
||||
<section>
|
||||
<title>Synchronous Reception</title>
|
||||
|
||||
<para>While JMS is typically associated with asynchronous processing, it
|
||||
is possible to consume messages synchronously. The overloaded
|
||||
<code>Receive(..)</code> methods provide this functionality. During a
|
||||
synchronous receive, the calling thread blocks until a message becomes
|
||||
available. This can be a dangerous operation since the calling thread
|
||||
can potentially be blocked indefinitely. The property
|
||||
<code><property>ReceiveTimeout</property></code> specifies how long the
|
||||
receiver should wait before giving up waiting for a message.</para>
|
||||
|
||||
<para>The <methodname>Receive</methodname> methods are listed
|
||||
below</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>public Message Receive()</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public Message Receive(Destination
|
||||
destination)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public Message Receive(string
|
||||
destinationName)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public Message ReceiveSelected(string
|
||||
messageSelector)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public Message ReceiveSelected(string destinationName,
|
||||
string messageSelector)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public Message ReceiveSelected(Destination destination,
|
||||
string messageSelector)</code></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The <methodname>Recieve</methodname> method without arguments used
|
||||
the <property>DefaultDestination</property>. The
|
||||
<methodname>RecieveSelected</methodname> methods apply the provided JMS
|
||||
message selector string to the <classname>MessageConsumer</classname>
|
||||
that is created.</para>
|
||||
|
||||
<para>The <methodname>ReceiveAndConvert</methodname> methods apply the
|
||||
templates message converter when receiving a message. These methods are
|
||||
listed below.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>public object ReceiveAndConvert()</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public object ReceiveAndConvert(Destination
|
||||
destination)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public object ReceiveAndConvert(string
|
||||
destinationName)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public object ReceiveSelectedAndConvert(string
|
||||
messageSelector)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public object ReceiveSelectedAndConvert(string
|
||||
destinationName, string messageSelector)</code></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><code>public object ReceiveSelectedAndConvert(Destination
|
||||
destination, string messageSelector)</code></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Asynchronous Reception</title>
|
||||
|
||||
<para>You can register a class that implements the
|
||||
<interfacename>IMessageListener</interfacename> interface. In the case
|
||||
of TIBCO EMS this interface is defined as</para>
|
||||
|
||||
<programlisting>public interface IMessageListener
|
||||
{
|
||||
void OnMessage(Message message);
|
||||
}</programlisting>
|
||||
|
||||
<para>Other vendors may provide a delegate based version of this
|
||||
interface.</para>
|
||||
|
||||
<para>You register you listener with a message listener container that
|
||||
specifies JMS configuration parameters and the number of concurrent
|
||||
consumers to create. There is an abstract base class for message
|
||||
listener containers,
|
||||
<classname>AbstractMessageListenerContainer</classname>, and one
|
||||
concrete implementation,
|
||||
<classname>SimpleMessageListenerContainer</classname>.
|
||||
<classname>SimpleMessageListenerContainer</classname> creates a fixed
|
||||
number of JMS Sessions/MessageConsumer pairs as set by the property
|
||||
<property>ConcurrentConsumers</property>. Here is a sample
|
||||
configuration</para>
|
||||
|
||||
<programlisting> <object id="connectionFactory" type="TIBCO.EMS.ConnectionFactory, TIBCO.EMS">
|
||||
<constructor-arg index="0" value="tcp://localhost:7222"/>
|
||||
</object>
|
||||
|
||||
<object id="messageListener" type="MyApp.MyMessageListener, MyApp"/>
|
||||
|
||||
<object id="jmsContainer" type="Spring.Messaging.Tibco.Ems.Listener.SimpleMessageListenerContainer, Spring.Messaging.Tibco.Ems">
|
||||
<property name="ConnectionFactory" ref="connectionFactory"/>
|
||||
<property name="DestinationName" value="APP.REQUEST"/>
|
||||
<property name="ConcurrentConsumers" value="10"/>
|
||||
<property name="MessageListener" ref="messageListener"/>
|
||||
</object></programlisting>
|
||||
|
||||
<para>The property <property>PubSubDomain</property> is by defalt false,
|
||||
meaning point-to-point/Queue delivery semantics. The above configuration
|
||||
will create 10 threads that process messages off of the queue named
|
||||
"APP.REQUEST". The threads are those owned by the JMS provider as a
|
||||
result of creating a JMS MessageConsumer. Other important properties are
|
||||
<property>ClientID</property>, used to set the ClientID of the JMS
|
||||
Connection and <property>MessageSelector</property> to specify the JMS
|
||||
'sql-like' message selector string. Durable subscriptions are supported
|
||||
via the properties <property>SubscriptionDurable</property> and
|
||||
<property>DurableSubscriptionName</property>. You may also register a
|
||||
listener using the property ExceptionListener.</para>
|
||||
|
||||
<section>
|
||||
<title>MessageListenerAdapater</title>
|
||||
|
||||
<para>The MessageListenerAdapter allows methods of a class that does
|
||||
not implement the IMessageListener interface to be invoked upon
|
||||
message delivery. Lets call this class the 'message handler' class. To
|
||||
achive this goal the MessageListenerAdapter implements the standard
|
||||
IMessageListener interface to recieve a message and then delegates the
|
||||
processing to the message handler class. Since the message handler
|
||||
class does not contain methods that refer to JMS artifacts such as
|
||||
Message,TextMessage etc, the MessageListenerAdapter uses a
|
||||
MessageConverter to bridge the JMS and 'plain object' worlds. As a
|
||||
reminder, the provided SimpleMessageConverter converts from
|
||||
TextMessage to string, BytesMessage to byte[], and MapMessage to
|
||||
IDictionary. Once the incoming message is converted to an IDictionary
|
||||
(for example) a method with the name 'Handle' is invoked via
|
||||
reflection passing in the IDictionary as an argument.</para>
|
||||
|
||||
<para>Using the SimpleMessageConverter, your "plain old object'
|
||||
messaging callback implementation would look like this.</para>
|
||||
|
||||
<programlisting>public class SimpleMessageHandler
|
||||
{
|
||||
public void HandleObject(IDictionary dict)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
public void HandleObject(string text)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
public void HandleObject(byte[] data)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>Notice how the various message handling methods are strongly
|
||||
typed according to the contents of the various Message types that they
|
||||
can receive and handle. The following configuration shows how to hook
|
||||
up this class to process incoming JMS messages.</para>
|
||||
|
||||
<para><programlisting>
|
||||
<object name="simpleMessageHandler, type="MyApp.SimpleMessageHandler, MyApp"/>
|
||||
|
||||
<object name="simpleMessageConverter"
|
||||
type="Spring.Messaging.Tibco.Ems.Support.Converter.SimpleMessageConverter, Spring.Messaging.Tibco.Ems"/>
|
||||
|
||||
<object id="messageListenerAdapter" type="Spring.Messaging.Tibco.Ems.Listener.Adapter.MessageListenerAdapter, ">
|
||||
<property name="DelegateObject" ref="simpleMessageHandler"/>
|
||||
<property name="DefaultListenerMethod" value="HandleObject"/>
|
||||
<property name="MessageConverter" ref="simpleMessageConverter"/>
|
||||
</object>
|
||||
|
||||
|
||||
<object id="connectionFactory" type="TIBCO.EMS.ConnectionFactory, TIBCO.EMS">
|
||||
<constructor-arg index="0" value="tcp://localhost:7222"/>
|
||||
</object>
|
||||
|
||||
<object id="jmsContainer" type="Spring.Messaging.Tibco.Ems.Listener.SimpleMessageListenerContainer, Spring.Messaging.Tibco.Ems">
|
||||
<property name="ConnectionFactory" ref="connectionFactory"/>
|
||||
<property name="DestinationName" value="APP.REQUEST"/>
|
||||
<property name="ConcurrentConsumers" value="10"/>
|
||||
<property name="MessageListener" ref="messageListener"/>
|
||||
</object></programlisting></para>
|
||||
|
||||
<para>Another of the capabilities of the MessageListenerAdapter class
|
||||
is the ability to automatically send back a response Message if a
|
||||
handler method returns a non-void value. Any non-null value that is
|
||||
returned from the execution of the handler method will (in the default
|
||||
configuration) be converted into a TextMessage. The resulting
|
||||
TextMessage will then be sent to the Destination (if one exists)
|
||||
defined in the JMS Reply-To property of the original Message, or the
|
||||
default Destination set on the MessageListenerAdapter (if one has been
|
||||
configured); if no Destination is found then an
|
||||
InvalidDestinationException will be thrown (and please note that this
|
||||
exception will not be swallowed and will propagate up the call
|
||||
stack).</para>
|
||||
|
||||
<para></para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>TIBCO Specific Details</title>
|
||||
|
||||
<para>Caching of JMS resources is usually done by a wrapping the 'raw
|
||||
provider' JMS implementation with an implementation that will cache JMS
|
||||
resources. The resources that are candidates for caching are the JMS
|
||||
Connection, Session, and MessageProducer. The JMS specification requires
|
||||
that the Connection be thread safe. The Session and MessageProducer are
|
||||
not required to be thread safe but they are in TIBCO's implementation. The
|
||||
most important resource to cache is the JMS Connection since the flow of
|
||||
events in JmsTemplate is to create/close a connection on each operation
|
||||
and this is an expensive operation. In the Java version of JmsTemplate a
|
||||
class, SingleConnectionFactory is provided in which the same Connection is
|
||||
returned on calls to createConnection() and all calls to .close() on the
|
||||
returned Connection are ignored. Since TIBCO's connection class does not
|
||||
have an interface nor virtual methods this strategy is not possible. An
|
||||
alternative strategy is to 'hard-code' the caching of these resources
|
||||
within JmsTemplate and SimpleMessageContainer. This functionality is
|
||||
controlled by the property <property>CacheJmsResources</property> and is
|
||||
set to true by default, resulting in caching of Connection, Session, and
|
||||
MessageProducer. When integration with NMS (a set of common interfaces for
|
||||
.NET JMS providers) is completed this will not be necessary and we can use
|
||||
a wrapper implementation of the NMS API that performs caching of JMS
|
||||
resources in an appropriate manner for each vendor.</para>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -130,7 +130,7 @@
|
||||
<para>Find below an example of the basic structure of XML-based
|
||||
configuration metadata.</para>
|
||||
|
||||
<programlisting><objects xmlns="http://www.springframework.net">
|
||||
<programlisting language="myxml"><objects xmlns="http://www.springframework.net">
|
||||
|
||||
<object id="..." type="...">
|
||||
<!-- collaborators and configuration for this object go here -->
|
||||
|
||||
209
doc/reference/src/scheduling.xml
Normal file
209
doc/reference/src/scheduling.xml
Normal file
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter id="scheduling">
|
||||
<title>Scheduling and Thread Pooling</title>
|
||||
|
||||
<section id="scheduling-introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>The Spring Framework features integration classes for scheduling
|
||||
support. Currently, Spring supports the Quartz Scheduler (<ulink
|
||||
url="http://quartznet.sourceforge.net/"></ulink>). The scheduler is set up
|
||||
using a <interfacename>IFactoryObject</interfacename> with optional
|
||||
references to <classname>Trigger</classname> instances, respectively.
|
||||
Furthermore, a convenience class for both the Quartz Scheduler is
|
||||
available that allows you to invoke a method of an existing target
|
||||
object.</para>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-quartz">
|
||||
<title>Using the Quartz.NET Scheduler</title>
|
||||
|
||||
<para>Quartz uses <classname>Trigger</classname>,
|
||||
<classname>Job</classname> and <classname>JobDetail</classname> objects to
|
||||
realize scheduling of all kinds of jobs. For the basic concepts behind
|
||||
Quartz, have a look at <ulink
|
||||
url="http://quartznet.sourceforge.net/"></ulink>. For convenience
|
||||
purposes, Spring offers a couple of classes that simplify the usage of
|
||||
Quartz within Spring-based applications.</para>
|
||||
|
||||
<section id="scheduling-quartz-jobdetail">
|
||||
<title>Using the JobDetailObject</title>
|
||||
|
||||
<para><classname>JobDetail</classname> objects contain all information
|
||||
needed to run a job. The Spring Framework provides a
|
||||
<classname>JobDetailObject</classname> that makes the
|
||||
<classname>JobDetail</classname> easier to configure and with sensible
|
||||
defaults. Let's have a look at an example:</para>
|
||||
|
||||
<programlisting>
|
||||
<object name="ExampleJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
|
||||
<property name="JobType" value="Example.Quartz.ExampleJob, Example.Quartz" />
|
||||
<property name="JobDataAsMap">
|
||||
<dictionary>
|
||||
<entry key="Timeout" value="5" />
|
||||
</dictionary>
|
||||
</property>
|
||||
</object></programlisting>
|
||||
|
||||
<para>The job detail object has all information it needs to run the job
|
||||
(<classname>ExampleJob</classname>). The timeout is specified in the job
|
||||
data dictionary. The job data dictonary is available through the
|
||||
<classname>JobExecutionContext</classname> (passed to you at execution
|
||||
time), but the <classname>JobDetailObject</classname> also maps the
|
||||
properties from the job data map to properties of the actual job. So in
|
||||
this case, if the <classname>ExampleJob</classname> contains a property
|
||||
named <literal>Timeout</literal>, the
|
||||
<classname>JobDetailObject</classname> will automatically apply
|
||||
it:</para>
|
||||
|
||||
<programlisting>namespace Example.Quartz;
|
||||
|
||||
public class ExampleJob extends QuartzJobObject {
|
||||
|
||||
private int timeout;
|
||||
|
||||
/// <summary>
|
||||
/// Setter called after the ExampleJob is instantiated
|
||||
/// with the value from the JobDetailObject (5)
|
||||
/// </summary>
|
||||
public int Timeout {
|
||||
set { timeout = value; };
|
||||
}
|
||||
|
||||
protected override void ExecuteInternal(JobExecutionContext context) {
|
||||
<lineannotation>// do the actual work</lineannotation>
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>All additional settings from the job detail object are of course
|
||||
available to you as well.</para>
|
||||
|
||||
<para><emphasis>Note: Using the <literal>name</literal> and
|
||||
<literal>group</literal> properties, you can modify the name and the
|
||||
group of the job, respectively. By default, the name of the job matches
|
||||
the object name of the job detail object (in the example above, this is
|
||||
<literal>ExampleJob</literal>).</emphasis></para>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-quartz-method-invoking-job">
|
||||
<title>Using the
|
||||
<classname>MethodInvokingJobDetailFactoryObject</classname></title>
|
||||
|
||||
<para>Often you just need to invoke a method on a specific object. Using
|
||||
the <classname>MethodInvokingJobDetailFactoryObject</classname> you can
|
||||
do exactly this:</para>
|
||||
|
||||
<programlisting><object id="JobDetail" class="Spring.Scheduling.Quartz.MethodInvokingJobDetailFactoryObject, Spring.Scheduling.Quartz">
|
||||
<property name="TargetObject" ref="ExampleBusinessObject" />
|
||||
<property name="TargetMethod" value="DoIt" />
|
||||
</object></programlisting>
|
||||
|
||||
<para>The above example will result in the <literal>doIt</literal>
|
||||
method being called on the <literal>exampleBusinessObject</literal>
|
||||
method (see below):</para>
|
||||
|
||||
<programlisting>public class ExampleBusinessObject {
|
||||
|
||||
<lineannotation>// properties and collaborators</lineannotation>
|
||||
|
||||
public void DoIt() {
|
||||
<lineannotation>// do the actual work</lineannotation>
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<programlisting>
|
||||
<object id="ExampleBusinessObject" class="Examples.BusinessObjects.ExampleBusinessObject, Examples.BusinessObjects"/></programlisting>
|
||||
|
||||
<para>Using the
|
||||
<classname>MethodInvokingJobDetailFactoryObject</classname>, you don't
|
||||
need to create one-line jobs that just invoke a method, and you only
|
||||
need to create the actual business object and wire up the detail
|
||||
object.</para>
|
||||
|
||||
<para>By default, Quartz Jobs are stateless, resulting in the
|
||||
possibility of jobs interfering with each other. If you specify two
|
||||
triggers for the same <classname>JobDetail</classname>, it might be
|
||||
possible that before the first job has finished, the second one will
|
||||
start. If <classname>JobDetail</classname> classes implement the
|
||||
<interfacename>Stateful</interfacename> interface, this won't happen.
|
||||
The second job will not start before the first one has finished. To make
|
||||
jobs resulting from the
|
||||
<classname>MethodInvokingJobDetailFactoryObject</classname>
|
||||
non-concurrent, set the <literal>concurrent</literal> flag to
|
||||
<literal>false</literal>.</para>
|
||||
|
||||
<programlisting><object id="JobDetail" class="Spring.Scheduling.Quartz.MethodInvokingJobDetailFactoryObject, Spring.Scheduling.Quartz">
|
||||
<property name="TargetObject" ref="ExampleBusinessObject" />
|
||||
<property name="TargetMethod" value="DoIt" />
|
||||
<property name="Concurrent" value="false" />
|
||||
</object>
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<para>By default, jobs will run in a concurrent fashion.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section id="scheduling-quartz-cron">
|
||||
<title>Wiring up jobs using triggers and the
|
||||
<classname>SchedulerFactoryObject</classname></title>
|
||||
|
||||
<para>We've created job details and jobs. We've also reviewed the
|
||||
convenience class that allows to you invoke a method on a specific
|
||||
object. Of course, we still need to schedule the jobs themselves. This
|
||||
is done using triggers and a
|
||||
<classname>SchedulerFactoryObject</classname>. Several triggers are
|
||||
available within Quartz. Spring offers two subclassed triggers with
|
||||
convenient defaults: <classname>CronTriggerObject</classname> and
|
||||
<classname>SimpleTriggerObject</classname></para>
|
||||
|
||||
<para>Triggers need to be scheduled. Spring offers a
|
||||
<classname>SchedulerFactoryObject</classname> that exposes triggers to
|
||||
be set as properties. <classname>SchedulerFactoryObject</classname>
|
||||
schedules the actual jobs with those triggers.</para>
|
||||
|
||||
<para>Find below a couple of examples:</para>
|
||||
|
||||
<programlisting><object id="SimpleTrigger" type="Spring.Scheduling.Quartz.SimpleTriggerObject, Spring.Scheduling.Quartz">
|
||||
<!-- see the example of method invoking job above -->
|
||||
<property name="JobDetail" ref="ExampleJob" />
|
||||
|
||||
<!-- 10 seconds -->
|
||||
<property name="StartDelay" value="10s" />
|
||||
|
||||
<!-- repeat every 50 seconds -->
|
||||
<property name="RepeatInterval" value="50s" />
|
||||
</object>
|
||||
|
||||
<object id="CronTrigger" type="Spring.Scheduling.Quartz.CronTriggerObject, Spring.Scheduling.Quartz">
|
||||
<property name="JobDetail" ref="ExampleJob" />
|
||||
|
||||
<!-- run every morning at 6 AM -->
|
||||
<property name="CronExpression" value="0 0 6 * * ?" />
|
||||
</object>
|
||||
</programlisting>
|
||||
|
||||
<para>Now we've set up two triggers, one running every 50 seconds with a
|
||||
starting delay of 10 seconds and one every morning at 6 AM. To finalize
|
||||
everything, we need to set up the
|
||||
<classname>SchedulerFactoryObject</classname>:</para>
|
||||
|
||||
<programlisting><object id="quartzSchedulerFactory" type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
|
||||
<property name="triggers">
|
||||
<list>
|
||||
<ref object="CronTrigger" />
|
||||
<ref object="SimpleTrigger" />
|
||||
</list>
|
||||
</property>
|
||||
</object>
|
||||
</programlisting>
|
||||
|
||||
<para>More properties are available for the
|
||||
<classname>SchedulerFactoryObjecct</classname> for you to set, such as
|
||||
the calendars used by the job details, properties to customize Quartz
|
||||
with, etc. Have a look at the <ulink
|
||||
url="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/scheduling/quartz/SchedulerFactoryBean.html">SchedulerFactoryObject
|
||||
SDK docs</ulink> for more information.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user