RE: OSGi @Reference setters

Jan Tošovský, modified 5 Years ago. Liferay Master Posts: 576 Join Date: 7/22/10 Recent Posts
I can see different styles when services are referenced inside components:
https://github.com/liferay/liferay-portal/blob/master/modules/apps/knowledge-base/knowledge-base-web/src/main/java/com/liferay/knowledge/base/web/internal/portlet/DisplayPortlet.java

@Reference
private KBArticleLocalService _kbArticleLocalService;

or
https://github.com/liferay/liferay-portal/blob/master/modules/apps/knowledge-base/knowledge-base-web/src/main/java/com/liferay/knowledge/base/web/internal/portlet/BaseKBPortlet.java

protected KBArticleService kbArticleService; 
@Reference(unbind = "-")
protected void setKBArticleService(KBArticleService kbArticleService) {
   this.kbArticleService = kbArticleService;
}
What is the main functional difference? Isn't there any risk of using none form instead of another?
thumbnail
David H Nebinger, modified 5 Years ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts
It's a matter of override really.

If you @Reference on a private field, it is what OSGi sets it to and no chance to inject.

If you @Reference on a public or protected setter, you give a subclass an opportunity to inject either a different service or the actual service if you're inheriting w/o the -dsannotations-options=include bnd.bnd directive.

Personally, I tend to build all of my classes with the appropriate getters and setters on a private field w/o the @Reference annotation first, but then I'll tack it on to the setter. I feel like this is sticking with standard Java techniques and allows for the class to be used in environments outside of OSGi (like spring or direct instantiation).  Not necessary since most of my code won't be used in any of those environments, but I still feel like I'm developing towards a set of "best practices" if there is such a thing.
thumbnail
Russell Bohl, modified 5 Years ago. Expert Posts: 308 Join Date: 2/13/13 Recent Posts
Believe this is the recommended way:

@Reference
private KBArticleLocalService _kbArticleLocalService;

I don't know exactly why the setters are commonly used, but I assume it has to do with being able to override them to mock the reference during testing?
thumbnail
Olaf Kock, modified 5 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts
Russell Bohl:

I don't know exactly why the setters are commonly used, but I assume it has to do with being able to override them to mock the reference during testing?
Another reason might also be that you can run code in addition to just setting a field's value - e.g. perform some extra initialization, logging, inspection or set a breakpoint to see what's injected and when. And all of that without explicitly implementing @Activate. Not that most of the setters aren't just setters anyway...
Jan Tošovský, modified 5 Years ago. Liferay Master Posts: 576 Join Date: 7/22/10 Recent Posts
<p>I thought setters are mainly used because you can specify that unbind = &quot;-&quot; property. If private fields are used, I suppose that default value is different.</p>

<p>I have some problems with one module, which somehow deactivates all my indexer post-processors from unrelated modules, so I am curious if that (missing) unbind can have some influence on this.</p>
thumbnail
Christoph Rabel, modified 5 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
The unbind method rarely matters. When a dependency is STATIC (== required), the module gets deactivated when the dependency goes away. So, it usually doesn't matter, whether the dependency is unset or not.
So, it probably has nothing to do with the issue (or did you set the reference policy OPTIONAL for some modules?)
thumbnail
Olaf Kock, modified 5 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts
Jan Tošovský:

I have some problems with one module, which somehow deactivates all my indexer post-processors from unrelated modules, so I am curious if that (missing) unbind can have some influence on this.
If there are any named components involved: Pay attention to them. I've recently seen the case that (for example) ServletFilters with conflicting names will cancel each other out. I'm not aware if such a problem might appear in your case, but it's worth looking for such occurrences.