The key differences between beans and OSGi services are:
- Beans are passive, beans are non-existent until someone creates them with Class.newInstance(). The whole idea of Inversion of Control (IoC) is that this creation is done by an outsider and not the POJO itself.
- You rarely require two beans of the same class. Why would you use two different database objects or log objects?
Unlike beans however OSGI services are more like "jumping beans" that have a life of their own. Spring attempts to provide room for this difference by injecting proxies to services into the configured bean instead of the service itself. This results in the following policies in regards to the binding of services summarized by Peter:
Mandatory/OptionalA mandatory service means that the service must be present before the application is activated and the application will be deactivated when there is no such service available anymore. An optional service does not influence the life cycle of the application. The declarative runtime can unbind a service and bind another service at will when the service is optional. Normal Spring beans are similar to mandatory services.
Mandatory is normally indicated in the cardinality as 1.., and optionality as 0.. .
Unary/Multiple
The application can be interested in a single service (unary) or it can track a set of services. The set may require some explanation. The dynamic service registry enables some very interesting software patterns. For example, one bundle manages a Bluetooth hardware interface. The whiteboard pattern shows that the simplest solution for this bundle is to register a service per discovered device, and unregister this service when the device is no longer reachable. Other bundles can then just track these services from the registry and use when required. This pattern nicely decouples the lifecycle of the bundles that participate, making clients easier to develop.
The idea that you can add and remove beans dynamically from a configured bean is new to Spring but it follows naturally from the OSGi model. This cardinality is indicated with ..1 for unary and ..n for multiple. Static/Dynamic
Once an application is activated because its dependencies are met, the lifecycle state of a referred service can change. The traditional choice is to deactivate the application and restart it when the conditions are right again; this is called the static policy. Some people are repelled by this idea but in an OSGi system this is quite natural, and well under the control of the operator. An update can cause a ripple effect of many bundles restarting but well designed systems should be robust enough to handle this. Hmm, let me rephrase, if your system can’t handle this model, it will fail in the end anyway.
In certain cases, it would do no harm to replace a service on the fly. If an application uses the Log Service, it is likely not interested which Log Service it uses. If this service is unregistered, it could easily be unbound and then bound again with a new instance. Most stateless services can be replaced this way. Binding and unbinding during the active life of the application is called the dynamic model.
Peter continues by breaking down a usage chart of possible combinations. He also advocates the Spring-OSGi specification becoming an offical OSGI R5 spec to promote continued cooperation.