Exposing Host Components via Spring
Atlassian Plugins comes with a Spring module that can be used to expose existing Spring beans to plugins either via XML or annotations.
Consuming host components
Before we get into exposing host components, it is worth discussing how to consume them. In a nutshell: simply use them in the constructions of your modules and components, and you'll get the instances injected.
The long answer is host components are exposed as OSGi services from the system bundle. If your plugin is a plain jar, during installation, the plugin framework will put it through a transformation pipeline to convert it to an OSGi bundle. As part of this, the framework generates any necessary Spring XML configuration files, one of which contains references to host components. The framework tries to scan your bytecode to see if you refer to the class of any host component, and if so, automatically generates a component-import, or more accurately, an OSGi service reference, to the host component service. With the host component now in the Spring bean factory, it is available for automatic injection by other Spring beans and module classes.
If using the annotation support in Spring 2.5 or later, you may wish to use annotations to mark spring beans that should be exposed to plugins as host components.
Assuming your Spring configuration is already configured to scan the classloader for classes with the @Component annotation, you can follow the following steps:
- Copy the atlassian-plugins-spring jar into your application. It contains a class called
SpringHostComponentProviderFactoryBean, which has the
@Componentannotation. This FactoryBean will create an instance of
- Consume the
HostComponentProviderin your class that instantiates the plugin framework, passing the
- Annotate any Spring components that you'd like to expose to plugins with the @AvailableToPlugins annotation. By default, this will expose the bean under all interfaces it discovers, but you can customise the specific interface by passing in the interface class as the default annotation value.
If you are already defining your beans in XML, it may be more natural to also mark them as available to plugins via XML. Assuming you are using Spring 2.0 or later, with XML namespace support, you can follow these steps:
- Copy the atlassian-plugins-spring jar into your application. It contains a
META-INF/spring.handlersfile, which defines the XML namespace to use.
Add the XML namespace to all applicable Spring XML configuration files. For example:
Use the new namespace in your XML, marking the desired beans as available to plugins with the "available" attribute. For example:
You can also customise the interfaces under which the bean is exposed via the "interface" sub-element: