On 13 Dec 2005, at 16:46, Jim Marino wrote:
Thanks for the feedback James! Some comments inline...

On Dec 13, 2005, at 6:53 AM, James Strachan wrote:

BTW I really like the SCA specification, though coming from a POJO / Spring background the distinction between @Reference and @Property seems a little surprising at first - I just wanted to describe my initial confusion and see if I'm on the right track to their intended differences and how they should be used.


Can you use @Property for services and @Reference for configuration values?
=============================================================

The specification seems to imply @Property is used to mark "a configuration property value" and @Reference is used to inject "a service that resolves the reference". For the moment lets ignore the difference between property injection by value versus by reference (we'll come on to that in a moment).

What is the real difference, from the perspective of an application programmer - between a service and a configuration property? It seems a fairly vague distinction - are there some rules the application developer can know when writing a POJO on what the difference between the two are. e.g. a JMS ConnectionFactory and a JDBC DataSource are probably configuration properties right?.

A service offers behavior and the reference may be decorated with QoS. A property is just a data value that does not offer fundamental behavior (of course a pojo data value could have some logic on it, but generally those are component implementation types)

So a component property value is really just a primitive type then? Or maybe something that can be coerced to/from a String? :). FWIW the latter is the definition Spring uses - it uses the Java Beans PropertyEditor to see if values can be read/written as strings.


The reason why we put this distinction into the spec (at one point we had them collapsed) was the ability to specify QoS on references as opposed to properties. If people think the distinction is more problematic than useful then we should definitely look at removing it. For example, one thing the distinction buys people is the ability to specify attributes specific to references, such as the potential autowire capability (see below). That may not be compelling enough. Do others have opinions here?

I do, however, like the distinction in SCDL for <references> and <properties>. We still need to distinguish between a component name in a reference and a string data value and that seems like a nice way to do it (it also groups stuff nicely). What do you think?

It does feel a little like different concepts are kinda being overloaded. How properties are configured (looking values up by name or not) seems to be quite separate to creating possibly remote references to services which may have additional QoS.

In Spring worlds I see folks inject by value and by reference both for primitive values and for services - they are both very useful.

e.g. I'm using DataSource here as a service; but its equally interchangable for primitive values too...

<!-- by value -->
<bean id="foo" class="SomeService">
        <property name="dataSource">
<!-- lets inject by value creating a new implementation -->
              <bean class="com.acme.MyDataSource">
                        <property uri="someuri"/>
                </bean>
        </bean>
</bean>

<!-- by reference (name) -->
<bean id="bar" class="SomeService">
<!-- the use of the @Reference could make this line unnecessary -->
        <property name="dataSource" ref="myDataSource"/>
</bean>


<!-- by reference (name) where the name comes from the @Reference annotation -->
<bean id="another" class="SomeService">
</bean>

So am wondering if injection by value or by reference should be a different concept to a 'possibly remote service reference with some QoS'.



Is a "service" in this case something which is @Remotable or has @Service? If either of those two are the case then can't the runtime figure out the difference based on the type without the application developer having to keep services & non-services in sync? Is the difference between the two really just that of by- value rather than by-reference configuration (and I was reading too much into the description of the annotations)?
@Remotable is used to define remotable services - the default, when no annotation is specified is local. @Service is optionally used to define the business interface of a local service in cases where it needs to be specified (i.e. the type may implement additional interfaces which are not business interfaces that should be exposed as a reference). References can be local or remote, so they can follow by-value or by-ref semantics. I may be missing something here since it is early so let me know.

I guess we're talking about two different things. Spring has a by- value and by-reference configuration mechanism as I've shown above; I'm kinda using this mental model (which I'm sure many Java developers these days share) - and was getting confused over the wording of the SCA spec which is why its confusing for me when you talk about by-value or by-ref semantics of @Reference.

The use of @Reference implies that the runtime will use the name you supply (or the property name if not) and look the service up by name - the name of the @Reference is the name of the service to inject. The value of this service is then injected into the property/field - but to me its still injection by reference, since you are using a name as an indirection. When injecting by value in Spring there is no name - so there is no worry that your 'dataSource' property name on service A might accidentally use the same 'dataSource' service of another component etc. So the by-value or by-reference distinction is quite handy.

Having said that; the @Property also has a name, so I guess @Property is injection could be by reference as well :). With my Spring-head on I'd kinda assumed the @Property.name was just used to rename the field/property in XML land; not to do a reference look up in some context. So (in a Spring sense) are both @Property and @Reference by reference (they look up the names in a context)?


I guess I'm really just highlighting where there is a conceptual clash with the POJO/Spring mental model and just wanted clarification. It might be useful to map the SCA annotations to how you may configure the POJOs in Spring (without any of the remoting stuff to start with) and understand how the annotations map to a Spring world to avoid confusion. e.g. a wiki page some place on 'what SCA annotations mean in a Spring container' or something. It would be good if Tuscany could sit on top of Spring as one possible Dependency Injection container without folks getting horribly confused with properties, references, services and by-value and by-reference.

i.e. there's a bunch of annotations which seem mostly to be to do with Dependency Injection and lifecycle (@Init, @Destroy, @Property, @Reference, @ComponentName) - it'd be interesting to see how they could map to Spring. As an experiment I hacked up a Spring PostProcessor to deal with most of the dependency injection annotations in SCA...

http://svn.xbean.org/trunk/sca/src/main/java/org/xbean/sca/ ScaBeanPostProcessor.java?rev=174&view=auto

I'm keen to ensure that POJOs can work well in both environments. Of course we could just completely ignore all the SCA annotations when deploying a POJO inside Spring but I think it'd be good Io encourage them to be reused in both SCA and pure Spring runtimes when they make sense (then many more folks might use them all the time, whether services are local or remote).


e.g. in Spring we can configure a service by name and inject it into a beans property whether it has no annotation, @Property or @Reference; so I'm wondering if the distinction between @Property and @Reference makes sense WRT configuration property value versus service - other than @Reference acts as a hint to the runtime to auto-wire the property value by using a named reference.

In SCA these annotations are also optional so if the implementation does not want to be aware of the distinction, it does not need to be as long as it does not have to specify a mandatory property or reference.

We are also looking to potentially add autowire capability (we may need it for the Tuscany runtime for "recursive injection" where module components or "aggregates" are assembled as pojos, which in turn contain other components, etc. In this case we want to wire things like a data binding component to a module component and do it by saying something to the effect of "for this type of component - a module component pojo - inject a component that implements this interface". This will allow us to use SCA to "assemble" the runtime.

Related to this, we have been discussing the usefulness of autowiring in general. A couple of very sketchy ideas we need to flush out are:

- The ability to specify autowire in the component type reference such as "wire a component the implements the interface specified by the reference or implements the interface specified by the reference and has the same name as the reference"

I've gotta say I'm a little uneasy at putting too much of this configuration into the annotations - unless its just a hint to the runtime - as its class level, not instance level configuration. e.g. I may want to auto-wire 1 set of POJOs of service in one XML config, but in the same JVM configure it quite differently (I may use the same service class with 2 different database connections or 2 different back end services for different customer groups).

There's an interesting blog entry which describes one solution using Spring and describes how its not necessarily ideal...
http://www.jroller.com/page/habuma/20051206



- The possibility of creating a way to describe auto-wiring, a type of "pointcut" expression language

Yeah - the stuff in Spring 2.0-M1 is well worth a look to see how the AOP BeanConfigurer works. I like being able to use annotations to create pointcuts in XML-land to configure things.


I would view things like DataSources as local (i.e. by ref) services that happen to be provided by the runtime as opposed to properties (basically "data" used for configuration that does not offer behavior).

Yeah - see my first part of the response in this mail - spring developers use both kinds of injection for things like DataSources. References tend to be used when you have many services sharing the same thing - there's nothing particularly special about the types involved & its typically outside of the POJO - the XML file - which decides if its good to use a reference or not.



So at first it seems a little surprising as to why a POJO needs to understand whether a property is set via direct property configuration (@Property) or via looking up some named reference (@Reference). It kinda feels wrong to make the POJO developer choose how its going to be configured - especially when one of SCA's goals is to hide middleware (which includes configuration).

I guess one effect of @Reference is that the container can automatically inject the named POJO without it explicitly being configured in some XML file. Maybe - considering Spring for a moment here - if we don't explicitly configure a property then the runtime would automatically inject it for us.

e.g.

public class Foo {
  @Reference(name="myBar")
  private Something bar;
  ...
}

the container would know how to inject the "bar" property by looking up myBar - so in Spring we could just do...

<bean id="myBean" class="Foo">
<!-- runtime automatically injects "bar" property -->
</bean>


Though I guess there's nothing to stop someone reusing Foo and explicitly configuring it in some runtime if they really want to...

<bean id="myBean" class="Foo">
  <!-- lets override the name used... ->
  <property name="bar" ref="aDifferentBar"/>
</bean>


I think autowire is useful in basic cases like this.

Agreed. I just wanted to highlight the need to overload/override the automatic autowiring sometimes. i.e. annotations should often just be a hint, the runtime may allow you to override things if necessary.


We should bring it up with the spec group.

Just out of interest; is the spec group a private separate mail list? It might be worth using a tuscany mail list for public discussions of the spec. I guess we could just reuse the dev list and use a [spec] prefix on subjects so folks can filter them out if they like.

James
-------
http://radio.weblogs.com/0112098/

Reply via email to