Differences between revisions 1 and 2
Revision 1 as of 2006-06-07 23:36:01
Size: 4251
Editor: JeremyBoynes
Comment:
Revision 2 as of 2009-09-20 22:47:34
Size: 4251
Editor: localhost
Comment: converted to 1.6 markup
No differences found!

A proposal to allow the use of non-default constructors in the Java Implementation model.

Rationale

The 0.9 version of the Java Client and Implementation Specification (Java Spec) requires that all implementations have a public, no-argument constructor that can be used by the container to instantiate instances of the component. All Property and Reference values are injected directly into fields or through setter methods.

However, some Java programmers prefer to pass these type of values in through constructor parameters. There are some cases where this is necessary, for example when the value is going to be stored in a final field. This proposal provides a mechanism that allows this style of injection as an additional alternative to the existing methods.

Proposal

A Java implementation class must provide a public or protected constructor that can be used by the container to instantiate the component. The constructor may contain parameters; in the presence of such parameters, the container will pass the applicable property or reference values when invoking the constructor. Any values not supplied in this manner will be set into the field or passed to the setter method associated with the property or reference before any service method is invoked.

The constructor to use must be selected by the container as follows:

  • A declared constructor annotated with a @Constructor annotation.
  • A declared constructor that unambiguously identifies all property and reference values.
  • A no-argument constructor.

The @Constructor annotation must only be specified on one constructor; the container must report an error if multiple constructors are so annotated.

The property or reference associated with each parameter of a constructor is identified by name in the @Constructor annotation (if present), though the presence of a @Property or @Reference annotation on the parameter declaration, or by uniquely matching the parameter type to the type of a property or reference defined by annotation of a field or setter method or declared in a sidefile.

Cyclic references between components may be handled by the container in one of two ways:

  • if any reference in the cycle is optional, then the container may inject a null value during construction, followed by injection of a reference to the target before invoking any service.
  • the container may inject a proxy to the target service; invocation of methods on the proxy may result in a ServiceUnavailableException

Annotation changes

This proposal introduces a new annotation that is used to identify the constructor:

package org.osoa.sca.annotations;
@Target(CONSTRUCTOR)
@Retention(RUNTIME)
public @interface Constructor {
    /** List of property or reference names associated with each parameter */
    String[] value();
}

In addition, the Property and Reference annotations are extended to allow placement on parameters:

@Target({METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface Property {
    ...
}

Examples

/** Simple class taking a single property value */
public class Impl1 {
    String someProperty;
    public Impl1(String propval) {...}
}

/** Simple class taking a property and reference in the constructor;
 * The values are not injected into the fields.
 *//
public class Impl2 {
    public String someProperty;
    public SomeService someReference;
    public Impl2(String a, SomeService b) {...}
}

/** Class declaring a named property and reference through the constructor */
public class Impl3 {
    @Constructor({"someProperty", "someReference"})
    public Impl3(String a, SomeService b) {...}
}

/** Class declaring a named property and reference through parameters */
public class Impl3b {
    public Impl3b(
        @Property("someProperty") String a, 
        @Reference("someReference) SomeService b
        ) {...}
}

/** Additional property set through a method */
public class Impl4 {
    public String someProperty;
    public SomeService someReference;
    public Impl2(String a, SomeService b) {...}
    @Property public void setAnotherProperty(int x) {...}
}

Tuscany/SpecProposals/Constructors (last edited 2009-09-20 22:47:34 by localhost)