Decoupling shared code with state that needs to cleared in between uses
1. Decoupling shared code with state
that needs to be
cleared/reinstantiated after each
use
Tim Fritschel
Michael Fons
2. Why are we here today, again?
• We are here to learn about method injection –
specifically a kind of method injection called
“lookup-method” in the Spring framework.
– What it is…
– How/why it is used…
– To walk through an actual example.
3. Why are we using Spring?
• Oracle 11g SOA seems to use it by default in
its configuration non-BPEL services.
• Our architects chose this for default
configuration for new services.
• Spring has many good features, of which we
want to take advantage – like…
– SCA integration
– Dependency injection
– Many other advantages
4. Is it more complicated to program in
Spring?
• Not really…mostly you just need to be aware
of what the configuration file is doing too.
• Mostly it is just a matter of getting used to it.
5. Is Dependency Injection any good?
• Dependency Injection has many advantages;
among them are…
– Separating configuration from use/interfaces from
implementation.
• Increasing testability.
• Changing implementations without changing the
dependent class.
• Promotes loose coupling and separation of
responsibilities.
• Promotes code readability and simplicity.
6. Is method injection like dependency
injection?
• The kind we are talking about is closely
related.
• This kind of method injection addresses an
issue with scoping, which I will cover a bit
later.
7. Can you give me a real example of
method injection?
• That’s exactly what I wanted to do next…
• Our example will involve sharing common
validation code in our SOA 11g framework.
• As part of the evolution of our S2F SOA 11g
architecture, we have debated with the
architecture team to choose whether to put this
shared code…
– In the project
– In the infrastructure library
– In it’s own service
8. Was your shared code complex? Did it
have state?
• Yes; the accumulation of error messages was
its “state”.
• Without clearing this state, or re-instantiating
the object, this state got garbled when called
multiple times for that singleton.
9. What do you mean, Singleton?
• Spring-managed beans have “scope.”
• Default scope is “singleton” – for each class
loader created, there is one instance created
by the spring context (at Web server startup?).
• “Prototype” scope can be selected – which
gets a new instance each time the dependent
class is instantiated.
10. What if we just make the shared code
“prototype” and left parent code
“singleton?”
• In order to see any real effect with making a
bean “prototype”, if it’s parent bean (i.e., the
bean we are injecting the prototype bean
into) is “singleton”, then we have two options
within Spring
– Make the parent “prototype” also.
– Use method injection (“lookup-method”) and
inject a factory method for the child bean, into the
parent bean.
11. What is wrong with making everything
prototype?
• Well, that means that every call of the service
gets a whole new set of objects allocated in
memory.
• That could be needlessly wasteful in some
cases, and could lead to server instability.
• I do not know if the architecture team has any
experimental data on this possibility. They
have not mentioned any yet…
12. OK…but “method injection” sounds
weird and complex…
• It’s not too bad…there is not really a difference in
the lines of code required.
• A group of us converted code that uses common
code that had to have its state cleared each time
because we had it set to singleton scope.
• With method-injection we were able to set this
common code bean to prototype, without
changing the parent bean from its default scope
of “singleton”.
13. Why is method injection needed in
this case?
• Look at
http://static.springsource.org/spring/docs/2.5
.x/spring-reference.pdf
• Within this document look at 3.3.7 and
3.3.7.1.
• If you do you will see the way we solved this
problem, was the default way to solve this
using Spring.
• This creates a factory method.
14. Are there other things you can do with
method injection in Spring other than
solving this scoping issue?
• Yes. For example, Tim Fritschel told me that in
a prior job he and his coworkers found a use
of a more complex kind of Spring method
injection to solve a particular kind of problem.
• Please ask him, or check Google/Spring
website for more information.
15. Couldn’t you have just used “new” to
create a new instance of VaoErrors?
• Yes, but VaoErrors required a datasource which was
also conveniently supplied in Spring configuration file.
• So with “new” the code would be messier, passing
datasource down with an additional parameter.
– Or further mix and match by adding a dataSource property
to the Vao implementation, and injecting it there.
• All this jumps around and increases code clutter and
detracts from the point of the code, making it less
readable.
18. Spring context has some bean
changes…
• Yes, there were two changes to spring context.
• There are two beans in use here…
– Vao – this is the parent bean, that is using
vaoErrors.
– vaoErrors – the child bean.
• Vao is Singleton scope.
• VaoErrors is “prototype” scope.
19. Can you explain the changes further?
• Vao has gone from direct property injection,
to injection via the “lookup-method” element.
– This creates a deploy-time implementation of the
createVaoErrors method in the vao bean
– When the method is called it will return an
instance of the vaoErrors bean (with the scope set
in spring configuration).
– VaoErrors bean changes its scope to prototype
now that we can use this scope without also
changing the scope of the vao bean!
21. OK. The parent object needs the
method we are injecting “declared”.
What else?
22. What the hell?
• OK, this is a bit weird, but listen…
– The “lookup-method” element actually instructs spring to sub-
class the parent bean, and create an implementation (or
override the existing implementation) of the specified method.
– The return-type of this method must be the same as the type of
the bean mentioned in the “lookup-method” element’s “bean”
attribute value.
– The name of the method must match the “name” attribute in
the lookup-method element.
– It should take no arguments.
– So since we will be implementing a method, it makes it easier to
remember to adjust for this by making the parent class
“abstract”. Alternatively you could create a method with a
don’t-care implementation, but this would be misleading.
23. OK. Fine. Is method injection better
than clearing the state?
• Using this technique trades clearing the state
with creating a new instance.
• After comparing these two approaches on
many different levels, these two seem to be
equivalent.
• Without the benefit of 20-20 hindsight, this
equivalence was not apparent at the time we
were considering our options; we thought we
were improving things.
25. OK, that makes sense. Added a factory
call before the validation, and
removed the “clearing” afterward.
Anything else?
• No, that is the last code change.
• If you have JUnit tests, you will need to alter
them a bit though.
26. Great. Is that hard?
• Not too bad. You have at least two choices
here
– Either subclass your parent and implement the
method which simply returns your new child bean
(VaoErrors in this case).
– Or create a test context in your SCA-INF/src in
project root, and copy in your bean definitions, so
that spring continues to implement this method
for you.
29. OK, I need a dataSource and the
parent and child beans. What else?
30. Need a property for the parent bean
and the context, and you need to
instantiate the context. What else?
31. Well, that’s all clean-up, right?
• Correct; the first change is because we no
longer need to inject our datasource into the
child since spring does this for us.
• The second change is to get the parent bean
from the context and store it on our test class
property we just created.
• The third change is more stuff that Spring
now does for use…dependency injection, etc.
33. Wow, I had not though of that!
• Yes, it’s true. You can actually conduct tests to
verify that your method injection is working
properly!
34. Hey man: thanks for the info, dude!
• Any time! See you at stand up!
35. What did you reference to get this
information?
• SOA 11g implementation experiences here as
S2F.
• http://martinfowler.com/articles/injection.ht
ml
• http://static.springsource.org/spring/docs/2.5
.x/spring-reference.pdf (especially chapter 3
and section 3.3.7)
• http://javapapers.com/spring/dependency-
injection-di-with-spring/#diadvantages
Editor's Notes
Code generation library for spring; found in lib/external on orion trunk.