Is is possible to create prototype scoped component in JIRA plugin? My intention is to create a different object on each dependency injection. Spring prototype scope seems to be intended for that reason. But annotation
@Scope
(
value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.TARGET_CLASS)
doesn't seems to have any effect on a component, which is effectively stays "singleton" (checked at runtime through ApplicationContext.isPrototype(String name)).
Well, I've come with next solution. Let's say, we want to define class com.example.proto.MyProtoBean as prototype bean.
1. We need to explicitly define Spring Context within "plugin-context.xml" file. In conjunction with atlassian-spring-scanner-2 settings it should look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:atlassian-scanner="http://www.atlassian.com/schema/atlassian-scanner/2"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.atlassian.com/schema/atlassian-scanner/2
http://www.atlassian.com/schema/atlassian-scanner/2/atlassian-scanner.xsd">
<atlassian-scanner:scan-indexes/>
<context:annotation-config/>
<context:component-scan base-package="com.example.proto"/>
</beans>
2. Important detail is to exclude given package from atlassian-spring-scanner plugin index: otherwise, it's going to be parsed as singleton bean. You can exclude package with <inclueExclude> in plugin configuration:
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<includeExclude>
-com.example.proto.*
</includeExclude>
<!--
You can also add verbose output to make sure that package is not parsed at all
<verbose>true</verbose>
-->
</configuration>
</plugin>
3. For prototype class it is enough to define @Scope annotation with value "prototype":
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyProtoBean {
// ...
}
4. Finally, inject bean in another class with ObjectFactory:
import com.example.proto.MyProtoBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ProtoUser {
private final MyProtoBean myProtoBean;
@Autowire
public ProtoUser(ObjectFactory<MyProtoBean> protoFactory) {
this.myProtoBean = protoFactory.getObject();
}
}
You can use other ways to inject prototype beans into a singleton instance, although I didn't test them.
@Vasil'ev Nickolay - you made my day today. This is not at all documented in the spring scanner, but worked perfectly fine when I ran into some problems with our app upgrade to Jira 10 where we also updated the spring scanner accordingly.
Thanks a lot.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.