Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
OSGi @Reference setters
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
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
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?
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.
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.
Believe this is the recommended way:
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?
private KBArticleLocalService _kbArticleLocalService;
@Reference
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?
Russell Bohl:
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...
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?
<p>I thought setters are mainly used because you can specify that unbind = "-" 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>
<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>
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?)
So, it probably has nothing to do with the issue (or did you set the reference policy OPTIONAL for some modules?)
Jan Tošovský:
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.
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.
Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™