This page explains how to convert your P2 app to use Spring Java configuration,
if it currently declares its components in its atlassian-plugin.xml
.
<Atlassian-Plugin-Key>
header to your AMPS <instructions>
, to indicate that your plugin should
not be transformed at runtime into an OSGi bundle. For example:1 2<project ...> <!-- ... --> <build> <plugins> <plugin> <groupId>com.atlassian.maven.plugins</groupId> <artifactId>amps-maven-plugin</artifactId> <!-- Or jira-maven-plugin, etc. --> <!-- For AMPS pre-8.0, use maven-amps-plugin, maven-jira-plugin, etc. --> <version>8.1.0</version> <configuration> <instructions> <!-- You may want to extract the plugin key to a POM property, for reuse elsewhere --> <Atlassian-Plugin-Key>my-plugin-key</Atlassian-Plugin-Key> <!-- You may need to import some packages whose usage is not detected by the maven-bundle-plugin, or mark some packages as optional, or add version ranges to them, etc. --> <Import-Package>*</Import-Package> <!-- Ensure the plugin is Spring-powered --> <Spring-Context>*</Spring-Context> <!-- ... --> </instructions> <!-- ... --> </configuration> </plugin> <!-- ... --> </plugins> </build> <!-- ... --> </project>
SpringBeans
, in a new package somewhere under
src/main/java
, for example com.example.myplugin.spring
.@org.springframework.context.annotation.Configuration
.You will currently have a Spring XML file in src/main/resources/META-INF/spring
(it could be called anything ending in
.xml). Modify this file as follows:
osgi
namespace from the root element.osgi
namespace with equivalent @Bean
methods in your Java config class.@Configuration
classes.For each service you’re importing via an osgi:reference
element in your Spring XML files (if any), create a method
like this in your Spring config class:
1 2@Bean(destroyMethod = "") public FooService fooService() { return importOsgiService(FooService.class); }
… where the importOsgiService
method is statically imported from com.atlassian.plugins.osgi.javaconfig.OsgiServices
.
The empty destroyMethod
attribute is only necessary if the service implements close()
or shutdown()
, for example
the CacheManager
API from atlassian-cache
; for most services, you can simply use @Bean
, with no attributes.
Do the same for each <component-import>
element in your plugin XML. Note that since version 0.2.0 of this helper
library, you can optionally specify an LDAP filter,
just as you could add a filter
attribute to <component-import>
. Here's an example that works with 0.3.1 and later:
1 2@Bean public FooService fooService() { return importOsgiService(FooService.class, ImportOptions.defaultOptions().withFilter("(some.key=some.value)")); }
Here, the FooService
will be imported only if it has a some.key
property with the value some.value
.
To import a collection of services as with osgi:list
or osgi:set
, since 0.6.0 the following approach may be used:
1 2@Bean public List<FooService> fooServices() { return importOsgiServiceCollection(list(FooService.class)); }
where importOsgiServiceCollection
is statically imported from com.atlassian.plugins.osgi.javaconfig.OsgiServices
and list
is a static factory method for com.atlassian.plugins.osgi.javaconfig.ServiceCollection
.
As opposed to importOsgiService
, the default "availability" for this method is "optional".
Replace each <component … public=”true”>
element in your plugin XML with a pair of methods like this in your Spring
config class:
1 2@Bean public BarService barService() { // TODO instantiate and return your BarService implementation } @Bean public FactoryBean<ServiceRegistration> exportBarService( final BarService barService) { return exportOsgiService(barService, ExportOptions.as(BarService.class)); }
… where the exportOsgiService
method is statically imported from com.atlassian.plugins.osgi.javaconfig.OsgiServices
.
You can also remove any @Named
or @Component
annotations from the class that implements BarService
(since you’re
now instantiating it programmatically).
Replace each <module-type>
element in your plugin XML with a pair of methods like this in your Spring config class:
1 2@Bean public ListableModuleDescriptorFactory myModuleDescriptorFactory() { return new MyModuleDescriptorFactory(); } @Bean public FactoryBean<ServiceRegistration> exportMyModuleType( final ListableModuleDescriptorFactory moduleDescriptorFactory) { return exportAsModuleType(moduleDescriptorFactory); }
… where the exportAsModuleType method is statically imported from com.atlassian.plugins.osgi.javaconfig.OsgiServices
.
If your @Configuration
class has become too big or messy, you can easily split it up as follows:
MyWebBeans.class
, or split up the beans by feature, etc).@Import
annotation that lists these subsidiary config classes,
for example:1 2@Configuration @Import({ MyPersistenceBeans.class, MyServiceBeans.class, MyWebBeans.class }) public class MainSpringConfig {}
Rate this page: