Spring FrameworkSource Level Metadata Support

Traducteur:  
(Dernière date de traduction:  )
Relecteur:  
(Dernière date de relecture:  )
Index des chapitres

Légende:
       à revoir
       non compris
       à faire
       non traduit ( laissé tel quel )

chapter
+ titleRef.   /chapter[1]/title[1]
OriginalTraduction
Source Level Metadata Support  
sect1
+ titleRef.   /chapter[1]/sect1[1]/title[1]
OriginalTraduction
Source-level metadata  
+ paraRef.   /chapter[1]/sect1[1]/para[1]
OriginalTraduction
Source-level metadata is the addition of attributes or annotations to program elements: usually, classes and/or methods.  
+ paraRef.   /chapter[1]/sect1[1]/para[2]
OriginalTraduction
For example, we might add metadata to a class as follows:  
+ programlistingRef.   /chapter[1]/sect1[1]/para[3]/programlisting[1]
OriginalTraduction
/**
 * Normal comments
 * @@org.springframework.transaction.interceptor.DefaultTransactionAttribute()
 */
public class PetStoreImpl implements PetStoreFacade, OrderService {
 
+ paraRef.   /chapter[1]/sect1[1]/para[4]
OriginalTraduction
We could add metadata to a method as follows:  
+ programlistingRef.   /chapter[1]/sect1[1]/para[5]/programlisting[1]
OriginalTraduction
/**
 * Normal comments
 * @@org.springframework.transaction.interceptor.RuleBasedTransactionAttribute ()
 * @@org.springframework.transaction.interceptor.RollbackRuleAttribute (Exception.class)
 * @@org.springframework.transaction.interceptor.NoRollbackRuleAttribute ("ServletException")
 */
public void echoException(Exception ex) throws Exception {
    ....
}
 
+ paraRef.   /chapter[1]/sect1[1]/para[6]
OriginalTraduction
Both these examples use Jakarta Commons Attributes syntax.  
+ paraRef.   /chapter[1]/sect1[1]/para[7]
OriginalTraduction
Source-level metadata was introduced to the mainstream with the release of Microsoft's .NET platform, which uses source-level attributes to control transactions, pooling and other behaviour.  
+ paraRef.   /chapter[1]/sect1[1]/para[8]
OriginalTraduction
The value in this approach has been recognized in the J2EE community. For example, it's much less verbose than the traditional XML deployment descriptors exclusively used by EJB. While it is desirable to externalize some things from program source code, some important enterprise settings--notably transaction characteristics--belong in program source. Contrary to the assumptions of the EJB spec, it seldom makes sense to modify the transactional characteristics of a method.  
+ paraRef.   /chapter[1]/sect1[1]/para[9]
OriginalTraduction
Although metadata attributes are typically used mainly by framework infrastructure to describe the services application classes require, it should also be possible for metadata attributes to be queried at runtime. This is a key distinction from solutions such as XDoclet, which primarily view metadata as a way of generating code such as EJB artefacts.  
+ paraRef.   /chapter[1]/sect1[1]/para[10]
OriginalTraduction
There are a number of solutions in this space, including:  
+ paraRef.   /chapter[1]/sect1[1]/itemizedlist[1]/listitem[1]/para[1]
OriginalTraduction
JSR-175: the standard Java metadata implementation, available in Java 1.5. But we need a solution now and may always want a facade  
+ paraRef.   /chapter[1]/sect1[1]/itemizedlist[1]/listitem[2]/para[1]
OriginalTraduction
XDoclet: well-established solution, primarily intended for code generation  
+ paraRef.   /chapter[1]/sect1[1]/itemizedlist[1]/listitem[3]/para[1]
OriginalTraduction
Various open source attribute implementations, pending the release of JSR-175, of which Commons Attributes appears to be the most promising. All these require a special pre- or post-compilation step.  
sect1
+ titleRef.   /chapter[1]/sect1[2]/title[1]
OriginalTraduction
Spring's metadata support  
+ paraRef.   /chapter[1]/sect1[2]/para[1]
OriginalTraduction
In keeping with its provision of abstractions over important concepts, Spring provides a facade to metadata implementations, in the form of the org.springframework.metadata.Attributes interface.  
+ paraRef.   /chapter[1]/sect1[2]/para[2]
OriginalTraduction
Such a facade adds value for several reasons:
+ paraRef.   /chapter[1]/sect1[2]/para[2]/itemizedlist[1]/listitem[1]/para[1]
OriginalTraduction
There is currently no standard metadata solution. Java 1.5 will provide one, but it is still in beta as of Spring 1.0. Furthermore, there will be a need for metadata support in 1.3 and 1.4 applications for at least two years. Spring aims to provide working solutions now; waiting for 1.5 is not an option in such an important area.  
+ paraRef.   /chapter[1]/sect1[2]/para[2]/itemizedlist[1]/listitem[2]/para[1]
OriginalTraduction
Current metadata APIs, such as Commons Attributes (used by Spring 1.0) are hard to test. Spring provides a simple metadata interface that is much easier to mock.  
+ paraRef.   /chapter[1]/sect1[2]/para[2]/itemizedlist[1]/listitem[3]/para[1]
OriginalTraduction
Even when Java 1.5 provides metadata support at language level, there will still be value in providing such an abstraction:  
+ paraRef.   /chapter[1]/sect1[2]/para[2]/itemizedlist[1]/listitem[3]/itemizedlist[1]/listitem[1]/para[1]
OriginalTraduction
JSR-175 metadata is static. It is associated with a class at compile time, and cannot be changed in a deployed environment. There is a need for hierarchical metadata, providing the ability to override certain attribute values in deployment--for example, in an XML file.  
+ paraRef.   /chapter[1]/sect1[2]/para[2]/itemizedlist[1]/listitem[3]/itemizedlist[1]/listitem[2]/para[1]
OriginalTraduction
JSR-175 metadata is returned through the Java reflection API. This makes it impossible to mock during test time. Spring provides a simple interface to allow this.  
 
+ paraRef.   /chapter[1]/sect1[2]/para[3]
OriginalTraduction
Thus Spring will support JSR-175 before Java 1.5 reaches GA, but will continue to offer an attribute abstraction API.  
+ paraRef.   /chapter[1]/sect1[2]/para[4]
OriginalTraduction
The Spring Attributes interface looks like this:  
+ programlistingRef.   /chapter[1]/sect1[2]/para[5]/programlisting[1]
OriginalTraduction
public interface Attributes {

    Collection getAttributes(Class targetClass);

    Collection getAttributes(Class targetClass, Class filter);

    Collection getAttributes(Method targetMethod);

    Collection getAttributes(Method targetMethod, Class filter);

    Collection getAttributes(Field targetField);

    Collection getAttributes(Field targetField, Class filter);
}
 
+ paraRef.   /chapter[1]/sect1[2]/para[6]
OriginalTraduction
This is a lowest common denominator interface. JSR-175 offers more capabilities than this, such as attributes on method arguments. As of Spring 1.0, Spring aims to provide the subset of metadata required to provide effective declarative enterprise services a la EJB or .NET. Beyond Spring 1.0, it is likely that Spring will provide further metadata methods.  
+ paraRef.   /chapter[1]/sect1[2]/para[7]
OriginalTraduction
Note that this interface offers Object attributes, like .NET. This distinguishes it from attribute systems such as that of Nanning Aspects and JBoss 4 (as of DR2), which offer only String attributes. There is a significant advantage in supporting Object attributes. It enables attributes to participate in class hierarchies and enables attributes to react intelligently to their configuration parameters.  
+ paraRef.   /chapter[1]/sect1[2]/para[8]
OriginalTraduction
In most attribute providers, attribute classes will be configured via constructor arguments or JavaBean properties. Commons Attributes supports both.  
+ paraRef.   /chapter[1]/sect1[2]/para[9]
OriginalTraduction
As with all Spring abstraction APIs, Attributes is an interface. This makes it easy to mock attribute implementations for unit tests.  
sect1
+ titleRef.   /chapter[1]/sect1[3]/title[1]
OriginalTraduction
Integration with Jakarta Commons Attributes  
+ paraRef.   /chapter[1]/sect1[3]/para[1]
OriginalTraduction
Presently Spring supports only Jakarta Commons Attributes out of the box, although it is easy to provide implementations of the org.springframework.metadata.Attributes interface for other metadata providers.  
+ paraRef.   /chapter[1]/sect1[3]/para[2]
OriginalTraduction
Commons Attributes 2.1 (http://jakarta.apache.org/commons/attributes/) is a capable attributes solution. It supports attribute configuration via constructor arguments and JavaBean properties, which offers better self-documentation in attribute definitions. (Support for JavaBean properties was added at the request of the Spring team.)  
+ paraRef.   /chapter[1]/sect1[3]/para[3]
OriginalTraduction
We've already seen two examples of Commons Attributes attributes definitions. In general, we will need to express:  
+ paraRef.   /chapter[1]/sect1[3]/itemizedlist[1]/listitem[1]/para[1]
OriginalTraduction
The name of the attribute class. This can be an FQN, as shown above. If the relevant attribute class has already been imported, the FQN isn't required. It's also possible to specify "attribute packages" in attribute compiler configuration.  
+ paraRef.   /chapter[1]/sect1[3]/itemizedlist[1]/listitem[2]/para[1]
OriginalTraduction
Any necessary parameterization, via constructor arguments or JavaBean properties  
+ paraRef.   /chapter[1]/sect1[3]/para[4]
OriginalTraduction
Bean properties look as follows:  
+ programlistingRef.   /chapter[1]/sect1[3]/para[5]/programlisting[1]
OriginalTraduction
/**
 * @@MyAttribute(myBooleanJavaBeanProperty=true)
 */
 
+ paraRef.   /chapter[1]/sect1[3]/para[6]
OriginalTraduction
It's possible to combine constructor arguments and JavaBean properties (as in Spring IoC).  
+ paraRef.   /chapter[1]/sect1[3]/para[7]
OriginalTraduction
Because, unlike Java 1.5 attributes, Commons Attributes is not integrated with the Java language, it is necessary to run a special attribute compilation step as part of the build process.  
+ paraRef.   /chapter[1]/sect1[3]/para[8]
OriginalTraduction
To run Commons Attributes as part of the build process, you will need to do the following.  
+ paraRef.   /chapter[1]/sect1[3]/para[9]
OriginalTraduction
1. Copy the necessary library Jars to $ANT_HOME/lib. Four Jars are required, and all are distributed with Spring:  
+ paraRef.   /chapter[1]/sect1[3]/itemizedlist[2]/listitem[1]/para[1]
OriginalTraduction
The Commons Attributes compiler Jar and API Jar  
+ paraRef.   /chapter[1]/sect1[3]/itemizedlist[2]/listitem[2]/para[1]
OriginalTraduction
xjavadoc.jar, from XDoclet  
+ paraRef.   /chapter[1]/sect1[3]/itemizedlist[2]/listitem[3]/para[1]
OriginalTraduction
commons-collections.jar, from Jakarta Commons  
+ paraRef.   /chapter[1]/sect1[3]/para[10]
OriginalTraduction
2. Import the Commons Attributes ant tasks into your project build script, as follows:  
+ programlistingRef.   /chapter[1]/sect1[3]/programlisting[1]
OriginalTraduction
<taskdef resource="org/apache/commons/attributes/anttasks.properties"/>
 
+ paraRef.   /chapter[1]/sect1[3]/para[11]
OriginalTraduction
3. Next, define an attribute compilation task, which will use the Commons Attributes attribute-compiler task to "compile" the attributes in the source. This process results in the generation of additional sources, to a location specified by the destdir attribute. Here we show the use of a temporary directory:  
+ programlistingRef.   /chapter[1]/sect1[3]/para[12]/programlisting[1]
OriginalTraduction
<target name="compileAttributes" >

    <attribute-compiler 
        destdir="${commons.attributes.tempdir}" 
    >
        <fileset dir="${src.dir}" includes="**/*.java"/>
    </attribute-compiler>

</target>
 
+ paraRef.   /chapter[1]/sect1[3]/para[13]
OriginalTraduction
The compile target that runs Javac over the sources should depend on this attribute compilation task, and must also compile the generated sources, which we output to our destination temporary directory. If there are syntax errors in your attribute definitions, they will normally be caught by the attribute compiler. However, if the attribute definitions are syntactically plausible, but specify invalid types or class names, the compilation of the generated attribute classes may fail. In this case, you can look at the generated classes to establish the cause of the problem.  
+ remarkRef.   /chapter[1]/sect1[3]/remark[1]
OriginalTraduction
Commons Attributes also provides Maven support. Please refer to Commons Attributes documentation for further information.  
+ paraRef.   /chapter[1]/sect1[3]/para[14]
OriginalTraduction
While this attribute compilation process may look complex, in fact it's a one-off cost. Once set up, attribute compilation is incremental, so it doesn't usually noticeably slow the build process. And once the compilation process is set up, you may find that use of attributes as described in this chapter can save you a lot of time in other areas.  
+ paraRef.   /chapter[1]/sect1[3]/para[15]
OriginalTraduction
If you require attribute indexing support (only currently required by Spring for attribute-targeted web controllers, discussed below), you will need an additional step, which must be performed on a Jar file of your compiled classes. In this, optional, step, Commons Attributes will create an index of all the attributes defined on your sources, for efficient lookup at runtime. This step looks as follows:  
+ programlistingRef.   /chapter[1]/sect1[3]/para[16]/programlisting[1]
OriginalTraduction
<attribute-indexer jarFile="myCompiledSources.jar">
    
    <classpath refid="master-classpath"/>

</attribute-indexer>
 
+ remarkRef.   /chapter[1]/sect1[3]/remark[2]
OriginalTraduction
See the /attributes directory of the Spring jPetStore sample application for an example of this build process. You can take the build script it contains and modify it for your own projects.  
+ paraRef.   /chapter[1]/sect1[3]/para[17]
OriginalTraduction
If your unit tests depend on attributes, try to express the dependency on the Spring Attributes abstraction, rather than Commons Attributes. Not only is this more portable--for example, your tests will still work if you switch to Java 1.5 attributes in future--it simplifies testing. Commons Attributes is a static API, while Spring provides a metadata interface that you can easily mock.  
sect1
+ titleRef.   /chapter[1]/sect1[4]/title[1]
OriginalTraduction
Metadata and Spring AOP autoproxying  
+ paraRef.   /chapter[1]/sect1[4]/para[1]
OriginalTraduction
The most important uses of metadata attributes are in conjunction with Spring AOP. This provides a .NET-like programming model, where declarative services are automatically provided to application objects that declare metadata attributes. Such metadata attributes can be supported out of the box by the framework, as in the case of declarative transaction management, or can be custom.  
+ paraRef.   /chapter[1]/sect1[4]/para[2]
OriginalTraduction
There is widely held to be a synergy between AOP and metadata attributes.  
sect2
+ titleRef.   /chapter[1]/sect1[4]/sect2[1]/title[1]
OriginalTraduction
Fundamentals  
+ paraRef.   /chapter[1]/sect1[4]/sect2[1]/para[1]
OriginalTraduction
This builds on the Spring AOP autoproxy functionality. Configuration might look like this:  
+ programlistingRef.   /chapter[1]/sect1[4]/sect2[1]/para[2]/programlisting[1]
OriginalTraduction
<bean id="autoproxy" 
    class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
</bean>

<bean id="transactionAttributeSource"
    class="org.springframework.transaction.interceptor.AttributesTransactionAttributeSource"
    autowire="constructor">
</bean>

<bean id="transactionInterceptor"
    class="org.springframework.transaction.interceptor.TransactionInterceptor"
    autowire="byType">
</bean>

<bean id="transactionAdvisor"
    class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"
    autowire="constructor" >
</bean>

<bean id="attributes"
    class="org.springframework.metadata.commons.CommonsAttributes"
/>
 
+ paraRef.   /chapter[1]/sect1[4]/sect2[1]/para[3]
OriginalTraduction
The basic concepts here should be familiar from the discussion of autoproxying in the AOP chapter.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[1]/para[4]
OriginalTraduction
The most important bean definitions are those named autoproxy and transactionAdvisor. Note that the actual bean names are not important; what matters is their class.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[1]/para[5]
OriginalTraduction
The autoproxy bean definition of class org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator will automatically advise ("autoproxy") all bean instances in the current factory based on matching Advisor implementations. This class knows nothing about attributes, but relies on Advisors' pointcuts matching. The pointcuts do know about attributes.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[1]/para[6]
OriginalTraduction
Thus we simply need an AOP advisor that will provide declarative transaction management based on attributes.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[1]/para[7]
OriginalTraduction
It's possible to add arbitrary custom Advisor implementations as well, and they will also be evaluated and applied automatically. (You can use Advisors whose pointcuts match on criteria besides attributes in the same autoproxy configuration, if necessary.)  
+ paraRef.   /chapter[1]/sect1[4]/sect2[1]/para[8]
OriginalTraduction
Finally, the attributes bean is the Commons Attributes Attributes implementation. Replace with another implementation of org.springframework.metadata.Attributes to source attributes from a different source.  
sect2
+ titleRef.   /chapter[1]/sect1[4]/sect2[2]/title[1]
OriginalTraduction
Declarative transaction management  
+ paraRef.   /chapter[1]/sect1[4]/sect2[2]/para[1]
OriginalTraduction
The commonest use of source-level attributes it to provide declarative transaction management a la .NET. Once the bean definitions shown above are in place, you can define any number of application objects requiring declarative transactions. Only those classes or methods with transaction attributes will be given transaction advice. You need to do nothing except define the required transaction attributes.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[2]/para[2]
OriginalTraduction
Unlike in .NET, you can specify transaction attributes at either class or method level. Class-level attributes, if specified, will be "inherited" by all methods. Method attributes will wholly override any class-level attributes.  
sect2
+ titleRef.   /chapter[1]/sect1[4]/sect2[3]/title[1]
OriginalTraduction
Pooling  
+ paraRef.   /chapter[1]/sect1[4]/sect2[3]/para[1]
OriginalTraduction
Again, as with .NET, you can enable pooling behavior via class-level attributes. Spring can apply this behavior to any POJO. You simply need to specify a pooling attribute, as follows, in the business object to be pooled:  
+ paraRef.   /chapter[1]/sect1[4]/sect2[3]/para[2]
OriginalTraduction
+ programlistingRef.   /chapter[1]/sect1[4]/sect2[3]/para[2]/programlisting[1]
OriginalTraduction
 /** 
 * @@org.springframework.aop.framework.autoproxy.target.PoolingAttribute (10)
 * 
 * @author Rod Johnson
 */
public class MyClass {
 
You'll need the usual autoproxy infrastructure configuration. You then need to specify a pooling TargetSourceCreator, as follows. Because pooling affects the creation of the target, we can't use a regular advice. Note that pooling will apply even if there are no advisors applicable to the class, if that class has a pooling attribute.
 
+ programlistingRef.   /chapter[1]/sect1[4]/sect2[3]/para[3]/programlisting[1]
OriginalTraduction
<bean id="poolingTargetSourceCreator"
    class="org.springframework.aop.framework.autoproxy.metadata.AttributesPoolingTargetSourceCreator"
    autowire="constructor" >
</bean>
 
+ paraRef.   /chapter[1]/sect1[4]/sect2[3]/para[4]
OriginalTraduction
The relevant autoproxy bean definition needs to specify a list of "custom target source creators", including the Pooling target source creator. We could modify the example shown above to include this property as follows:  
+ programlistingRef.   /chapter[1]/sect1[4]/sect2[3]/para[5]/programlisting[1]
OriginalTraduction
<bean id="autoproxy" 
    class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
>
    <property name="customTargetSourceCreators">
        <list>
            <ref local="poolingTargetSourceCreator" />
        </list>
    </property>
</bean>
 
+ paraRef.   /chapter[1]/sect1[4]/sect2[3]/para[6]
OriginalTraduction
As with the use of metadata in Spring in general, this is a one-off cost: once setup is out of the way, it's very easy to use pooling for additional business objects.  
+ remarkRef.   /chapter[1]/sect1[4]/sect2[3]/remark[1]
OriginalTraduction
It's arguable that the need for pooling is rare, so there's seldom a need to apply pooling to a large number of business objects. Hence this feature does not appear to be used often.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[3]/para[7]
OriginalTraduction
Please see the Javadoc for the org.springframework.aop.framework.autoproxy package for more details. It's possible to use a different pooling implementation than Commons Pool with minimal custom coding.  
sect2
+ titleRef.   /chapter[1]/sect1[4]/sect2[4]/title[1]
OriginalTraduction
Custom metadata  
+ paraRef.   /chapter[1]/sect1[4]/sect2[4]/para[1]
OriginalTraduction
We can even go beyond the capabilities of .NET metadata attributes, because of the flexibility of the underlying autoproxying infrastructure.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[4]/para[2]
OriginalTraduction
We can define custom attributes, to provide any kind of declarative behavior. To do this, you need to:  
+ paraRef.   /chapter[1]/sect1[4]/sect2[4]/itemizedlist[1]/listitem[1]/para[1]
OriginalTraduction
Define your custom attribute class  
+ paraRef.   /chapter[1]/sect1[4]/sect2[4]/itemizedlist[1]/listitem[2]/para[1]
OriginalTraduction
Define a Spring AOP Advisor with a pointcut that fires on the presence of this custom attribute.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[4]/itemizedlist[1]/listitem[3]/para[1]
OriginalTraduction
Add that Advisor as a bean definition to an application context with the generic autoproxy infrastructure in place.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[4]/itemizedlist[1]/listitem[4]/para[1]
OriginalTraduction
Add attributes to your POJOs.  
+ paraRef.   /chapter[1]/sect1[4]/sect2[4]/para[3]
OriginalTraduction
There are several potential areas you might want to do this, such as custom declarative security, or possibly caching.  
+ remarkRef.   /chapter[1]/sect1[4]/sect2[4]/remark[1]
OriginalTraduction
This is a powerful mechanism which can significantly reduce configuration effort in some projects. However, remember that it does rely on AOP under the covers. The more Advisors you have in play, the more complex your runtime configuration will be.  
+ remarkRef.   /chapter[1]/sect1[4]/sect2[4]/remark[2]
OriginalTraduction
(If you want to see what advice applies to any object, try casting a reference to org.springframework.aop.framework.Advised. This will enable you to examine the Advisors.)  
sect1
+ titleRef.   /chapter[1]/sect1[5]/title[1]
OriginalTraduction
Using attributes to minimize MVC web tier configuration  
+ paraRef.   /chapter[1]/sect1[5]/para[1]
OriginalTraduction
The other main use of Spring metadata as of 1.0 is to provide an option to simplify Spring MVC web configuration.  
+ paraRef.   /chapter[1]/sect1[5]/para[2]
OriginalTraduction
Spring MVC offers flexible handler mappings: mappings from incoming request to controller (or other handler) instance. Normally handler mappings are configured in the xxxx-servlet.xml file for the relevant Spring DispatcherServlet.  
+ paraRef.   /chapter[1]/sect1[5]/para[3]
OriginalTraduction
Holding these mappings in the DispatcherServlet configuration file is normally A Good Thing. It provides maximum flexibility. In particular:
+ paraRef.   /chapter[1]/sect1[5]/para[3]/itemizedlist[1]/listitem[1]/para[1]
OriginalTraduction
The controller instance is explicitly managed by Spring IoC, through an XML bean definition  
+ paraRef.   /chapter[1]/sect1[5]/para[3]/itemizedlist[1]/listitem[2]/para[1]
OriginalTraduction
The mapping is external to the controller, so the same controller instance could be given multiple mappings in the same DispatcherServlet context or reused in a different configuration.  
+ paraRef.   /chapter[1]/sect1[5]/para[3]/itemizedlist[1]/listitem[3]/para[1]
OriginalTraduction
Spring MVC is able to support mappings based on any criteria, rather than merely the request URL-to-controller mappings available in most other frameworks.  
 
+ paraRef.   /chapter[1]/sect1[5]/para[4]
OriginalTraduction
However, this does mean that for each controller we typically need both a handler mapping (normally in a handler mapping XML bean definition) and an XML mapping for the controller itself.  
+ paraRef.   /chapter[1]/sect1[5]/para[5]
OriginalTraduction
Spring offers a simpler approach based on source-level attributes, which is an attractive option in simpler scenarios.  
+ remarkRef.   /chapter[1]/sect1[5]/remark[1]
OriginalTraduction
The approach described in this section is best suited to relatively simple MVC scenarios. It sacrifices some of the power of Spring MVC, such as the ability to use the same controller with different mappings, and the ability to base mappings on something other than request URL.  
+ paraRef.   /chapter[1]/sect1[5]/para[6]
OriginalTraduction
In this approach, controllers are marked with one or more class-level metadata attributes, each specifying one URL they should be mapped to.  
+ paraRef.   /chapter[1]/sect1[5]/para[7]
OriginalTraduction
The following examples show the approach. In each case, we have a controller that depends on a business object of type Cruncher. As usual, this dependency will be resolved by Dependency Injection. The Cruncher must be available through a bean definition in the relevant DispatcherServlet XML file, or a parent context.  
+ paraRef.   /chapter[1]/sect1[5]/para[8]
OriginalTraduction
We attach an attribute to the controller class specifying the URL that should map to it. We can express the dependency through a JavaBean property or a constructor argument. This dependency must be resolvable by autowiring: that is, there must be exactly one business object of type Cruncher available in the context.  
+ programlistingRef.   /chapter[1]/sect1[5]/para[9]/programlisting[1]
OriginalTraduction
/**
 * Normal comments here
 * @author Rod Johnson
 * @@org.springframework.web.servlet.handler.metadata.PathMap("/bar.cgi")
 */
public class BarController extends AbstractController {

    private Cruncher cruncher;

    public void setCruncher(Cruncher cruncher) {
        this.cruncher = cruncher;
    }

    protected ModelAndView handleRequestInternal(
            HttpServletRequest arg0, HttpServletResponse arg1) 
            throws Exception {
        System.out.println("Bar Crunching c and d =" + 
            cruncher.concatenate("c", "d"));
        return new ModelAndView("test");
    }

}
 
+ paraRef.   /chapter[1]/sect1[5]/para[10]
OriginalTraduction
For this auto-mapping to work, we need to add the following to the relevant xxxx-servlet.xml file, specifying the attributes handler mapping. This special handler mapping can handle any number of controllers with attributes as shown above. The bean id ("commonsAttributesHandlerMapping") is not important. The type is what matters:  
+ programlistingRef.   /chapter[1]/sect1[5]/para[11]/programlisting[1]
OriginalTraduction
<bean id="commonsAttributesHandlerMapping"      
    class="org.springframework.web.servlet.handler.metadata.CommonsPathMapHandlerMapping"
/>
 
+ paraRef.   /chapter[1]/sect1[5]/para[12]
OriginalTraduction
We do not currently need an Attributes bean definition, as in the above example, because this class works directly with the Commons Attributes API, not via the Spring metadata abstraction.  
+ paraRef.   /chapter[1]/sect1[5]/para[13]
OriginalTraduction
We now need no XML configuration for each controller. Controllers are automatically mapped to the specified URL(s). Controllers benefit from IoC, using Spring's autowiring capability. For example, the dependency expressed in the "cruncher" bean property of the simple controller shown above is automatically resolved in the current web application context. Both Setter and Constructor Dependency Injection are available, each with zero configuration.  
+ paraRef.   /chapter[1]/sect1[5]/para[14]
OriginalTraduction
An example of Constructor Injection, also showing multiple URL paths:  
+ programlistingRef.   /chapter[1]/sect1[5]/para[15]/programlisting[1]
OriginalTraduction
/**
* Normal comments here
* @author Rod Johnson
* 
* @@org.springframework.web.servlet.handler.metadata.PathMap("/foo.cgi")
* @@org.springframework.web.servlet.handler.metadata.PathMap("/baz.cgi")
*/
public class FooController extends AbstractController {

    private Cruncher cruncher;

    public FooController(Cruncher cruncher) {
        this.cruncher = cruncher;
    }

    protected ModelAndView handleRequestInternal(
            HttpServletRequest arg0, HttpServletResponse arg1) 
            throws Exception {
        return new ModelAndView("test");
    }

}
 
+ paraRef.   /chapter[1]/sect1[5]/para[16]
OriginalTraduction
This approach has the following benefits:  
+ paraRef.   /chapter[1]/sect1[5]/itemizedlist[1]/listitem[1]/para[1]
OriginalTraduction
Significantly reduced volume of configuration. Each time we add a controller we need add no XML configuration. As with attribute-driven transaction management, once the basic infrastructure is in place, it is very easy to add more application classes.  
+ paraRef.   /chapter[1]/sect1[5]/itemizedlist[1]/listitem[2]/para[1]
OriginalTraduction
We retain much of the power of Spring IoC to configure controllers.  
+ paraRef.   /chapter[1]/sect1[5]/para[17]
OriginalTraduction
This approach has the following limitations:  
+ paraRef.   /chapter[1]/sect1[5]/itemizedlist[2]/listitem[1]/para[1]
OriginalTraduction
One-off cost in more complex build process. We need an attribute compilation step and an attribute indexing step. However, once in place, this should not be an issue.  
+ paraRef.   /chapter[1]/sect1[5]/itemizedlist[2]/listitem[2]/para[1]
OriginalTraduction
Currently Commons Attributes only, although support for other attribute providers may be added in future.  
+ paraRef.   /chapter[1]/sect1[5]/itemizedlist[2]/listitem[3]/para[1]
OriginalTraduction
Only "autowiring by type" dependency injection is supported for such controllers. However, this still leaves them far in advance of Struts Actions (with no IoC support from the framework) and, arguably, WebWork Actions (with only rudimentary IoC support) where IoC is concerned.  
+ paraRef.   /chapter[1]/sect1[5]/itemizedlist[2]/listitem[4]/para[1]
OriginalTraduction
Reliance on automagical IoC resolution may be confusing.  
+ paraRef.   /chapter[1]/sect1[5]/para[18]
OriginalTraduction
Because autowiring by type means there must be exactly one dependency of the specified type, we need to be careful if we use AOP. In the common case using TransactionProxyFactoryBean, for example, we end up with two implementations of a business interface such as Cruncher: the original POJO definition, and the transactional AOP proxy. This won't work, as the owning application context can't resolve the type dependency unambiguously. The solution is to use AOP autoproxying, setting up the autoproxy infrastructure so that there is only one implementation of Cruncher defined, and that implementation is automatically advised. Thus this approach works well with attribute-targeted declarative services as described above. As the attributes compilation process must be in place to handle the web controller targeting, this is easy to set up.  
+ paraRef.   /chapter[1]/sect1[5]/para[19]
OriginalTraduction
Unlike other metadata functionality, there is currently only a Commons Attributes implementation available: org.springframework.web.servlet.handler.metadata.CommonsPathMapHandlerMapping. This limitation is due to the fact that not only do we need attribute compilation, we need attribute indexing: the ability to ask the attributes API for all classes with the PathMap attribute. Indexing is not currently offered on the org.springframework.metadata.Attributes abstraction interface, although it may be in future. (If you want to add support for another attributes implementation--which must support indexing--you can easily extend the AbstractPathMapHandlerMapping superclass of CommonsPathMapHandlerMapping, implementing the two protected abstract methods to use your preferred attributes API.)  
+ paraRef.   /chapter[1]/sect1[5]/para[20]
OriginalTraduction
Thus we need two additional steps in the build process: attribute compilation and attribute indexing. Use of the attribute indexer task was shown above. Note that Commons Attributes presently requires a Jar file as input to indexing.  
+ remarkRef.   /chapter[1]/sect1[5]/remark[2]
OriginalTraduction
If you begin with a handler metadata mapping approach, it is possible to switch at any point to a classic Spring XML mapping approach. So you don't close off this option. For this reason, I find that I often start a web application using metadata mapping.  
sect1
+ titleRef.   /chapter[1]/sect1[6]/title[1]
OriginalTraduction
Other uses of metadata attributes  
+ paraRef.   /chapter[1]/sect1[6]/para[1]
OriginalTraduction
Other uses of metadata attributes appear to be growing in popularity. As of March 2004, an attribute-based validation package for Spring is in development. The one-off setup cost of attribute parsing looks more attractive, when the potential for multiple uses is considered.  
sect1
+ titleRef.   /chapter[1]/sect1[7]/title[1]
OriginalTraduction
Adding support for additional metadata APIs  
+ paraRef.   /chapter[1]/sect1[7]/para[1]
OriginalTraduction
Should you wish to provide support for another metadata API it is easy to do so.  
+ paraRef.   /chapter[1]/sect1[7]/para[2]
OriginalTraduction
Simply implement the org.springframework.metadata.Attributes interface as a facade for your metadata API. You can then include this object in your bean definitions as shown above.  
+ paraRef.   /chapter[1]/sect1[7]/para[3]
OriginalTraduction
All framework services that use metadata, such as AOP metadata-driven autoproxying, will then automatically be able to use your new metadata provider.  
+ remarkRef.   /chapter[1]/sect1[7]/remark[1]
OriginalTraduction
We expect to add support for Java 1.5 attributes--probably as an add-on to the Spring core--in Q2 2004.  


Index des chapitres