BadPractice13 - SpotBugsExtensionForSpringFrameWork/CS5098 GitHub Wiki
Bug Pattern Name: COLLECTION_TYPE_INEXPLICIT_INJECTION
Short Description: Use @Resource over @Autowire + @Qualifier for collection type injection (to shorten your code).
"If you intend to express annotation-driven injection by name, do not primarily use @Autowired - even if is technically capable of referring to a bean name through @Qualifier values. Instead, prefer the JSR-250 @Resource annotation which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process." spring docs
"You may wonder why the annotation @Resource is used instead of @Autowired. It’s because the @Autowired annotation is semantically defined in a way that it always treats arrays, collections, and maps as sets of corresponding beans, with the target bean type derived from the declared collection value type. So, **for example**, if a class has an attribute of type List and has the @Autowired annotation defined, **Spring will try to inject all beans of type ContentHolder** within the current ApplicationContext into that attribute (instead of the declared in the configuration file), **which will result in either the unexpected dependencies being injected or Spring throwing an exception if no bean of type ContentHolder was defined**. So, for collection type injection, we have to explicitly instruct Spring to perform injection by specifying the bean name, which the @Resource annotation supports." (Pro Spring 5)
@Service("injectCollection")
public class CollectionInjection {
//@Resource(name="map") is equivalent with @Autowired @Qualifier("map")
@Autowired
@Qualifier("map")
private Map<String, Object> map;
@Resource(name="props")
private Properties props;
@Resource(name="set")
private Set set;
@Resource(name="list")
private List list;
}
<beans ...>
<bean id="lyricHolder"
lass="com.apress.prospring5.ch3.xml.LyricHolder"/>
<bean id="injectCollection"
class="com.apress.prospring5.ch3.xml.CollectionInjection">
<property name="map">
<map>
<entry key="someValue">
<value>It's a Friday, we finally made it</value>
</entry>
<entry key="someBean">
<ref bean="lyricHolder"/>
</entry>
</map>
</property>
<property name="props">
<props>
<prop key="firstName">John</prop>
<prop key="secondName">Mayer</prop>
</props>
</property>
<property name="set">
<set>
<value>I can't believe I get to see your face</value>
<ref bean="lyricHolder"/>
</set>
</property>
<property name="list">
<list>
<value>You've been working and I've been waiting</value>
<ref bean="lyricHolder"/>
</list>
</property>
</bean>
</beans>
- Pro Spring 5 (84 page)
- https://stackoverflow.com/questions/53578270/spring-using-resource-over-autowired-for-better-performance
- https://stackoverflow.com/questions/9106416/difference-between-qualifier-and-resource
- https://stackoverflow.com/questions/20450902/inject-and-resource-and-autowired-annotations/20451954#20451954