Java Reference
In-Depth Information
The problem with consuming
OSG
i services is greatly magnified when a bundle relies
on more than one; in fact this code is sufficiently complex that most people get it
wrong. You can use a simpler
OSG
i
API
, called the
ServiceTracker
, to consume ser-
vices (see appendix A for more detail). The
ServiceTracker
makes consuming a ser-
vice easier, but things quickly become unmanageable if you need to consume more
than one in a thread-safe way. It's for this reason that we always recommend using a
dependency injection framework to consume
OSG
i services. It's not that you can't do
it yourself, but we don't recommend it. (We suspect the complexity of the
OSG
i ser-
vices
API
may be one of the reasons
OSG
i services haven't yet taken the software world
by storm, despite their usefulness.) Dependency injection frameworks eliminate
almost all of the hassle of using
OSG
i services. But avoiding complexity isn't the only
reason to use dependency injection—there are lots of other advantages to using a
dependency injection framework in
OSG
i.
Not only is it tricky to get right, consuming services programmatically isn't terribly
efficient unless you're super-careful to optimize. Service instances (or service facto-
ries) need to be instantiated, even if nothing ever ends up looking up those services. If
unget()
isn't called on looked-up services, classloaders may be held in memory
unnecessarily. And
OSG
i dynamics mean that using services can be like walking
through quicksand. At its best, dependency injection offers identical performance to
using the programmatic service
API
and protects developers from the sometimes hairy
dynamics of
OSG
i services without sacrificing anything in terms of dynamism or even
the ability to respond to system changes. As you'll see, there's no shortage of depen-
dency injection frameworks to choose from, either. We'll discuss four of the more pop-
ular
OSG
i-enabled frameworks: Blueprint, Declarative Services, iPojo, and Peaberry.
6.2.2
Blueprint
In general, we believe the most suitable dependency injection framework for enter-
prise
OSG
i programming is Blueprint. Not only is it well integrated with other enter-
prise
OSG
i technologies, it acts as an integration point for many of them. For
example, container-managed persistence and container-managed transactions use
Blueprint for their metadata.
Because Blueprint is an open standard based on the Spring Framework, the
XML
syntax will be familiar to most Java
EE
developers. Blueprint also offers the best sup-
port of all the dependency injection frameworks for combining service injection with
normal Java constructs like static factory methods and constructed objects. Finally, by
using proxies, Blueprint insulates you and your application most effectively from
some of the less welcome parts of
OSG
i dynamism.
6.2.3
Declarative Services
But Blueprint isn't the only technology in town for managing
OSG
i services declara-
tively. An earlier specification, Declarative Services (
DS
), is also popular. In broad
terms, Declarative Services is lighter-weight but less feature-rich than Blueprint-
managed services. You may therefore find that Declarative Services offers slightly