Access components statically
Any class defined in a module descriptor will be created and autowired automatically by Spring, optionally injecting host components, imported components, and components defined in your plugin. However, there are several cases, such as Confluence Jobs, where your object cannot be created via Spring and therefore, you need to find another way to access a component.
The solution is to create a component that is injected with everything you need that then exposes those beans as static methods. For example, you could define this component in your
StaticAccessor as follows:
In this example, SpaceManager is a Confluence host component, PluginSettingsFactory is an imported component from SAL, and MyComponent is a component defined in your plugin.
Finally, in your class that can't be injected, you can now easily access the components you need statically from StaticAccessor.
This technique contains several patterns that are generally very bad, but acceptable here:
- Static variables will be null if accessed before the object is constructed. However, as long as you don't try to call StaticAccessor from a constructor, the variables will be guaranteed to be assigned before access.
- Static state is generally thought of to be type of global variable, however since the class is loaded as part of an OSGi bundle, you can think of it scoped to the bundle's lifecycle - when the plugin is uninstalled, the state goes away. However, be aware that even if the plugin is disabled, the ClassLoader for that bundle, which contains a direct reference on the StaticAccessor class and therefore, its static variables, will still be around. Since this technique only advocates storing static references to defined components, this shouldn't be a problem.