문제

I've come across a case where I want to use Blueprint (Aries) to resolve a dependency at run-time and the implementation is defined in the same bundle which requires it and will not be used in any other bundles. I am abstracting the implementation within this bundle to make it easier to mock the dependency when unit testing. If I put this service in its own bundle, it would lead to poor cohesion.

At run-time, the Blueprint says it is waiting for dependencies. How can I use Blueprint to realize dependency injection within a bundle?

<!-- Interface -->
<reference id="modelEntityMapper" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />
<!-- Implementation defined within same bundle -->
<bean id="modelEntityMapperImpl" class="org.example.blog.rest.cxf.server.model.impl.ModelEntityMapperImpl" />
<service ref="modelEntityMapperImpl" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />

<!-- Object which has dependency -->
<bean id="posts" class="org.example.blog.rest.cxf.server.BlogResourceImpl">
        <property name="modelEntityMapper" ref="modelEntityMapper" />
</bean>

Edit

I just tried the suggestion from @christian-scheider and Blueprint is still waiting for some service to satisfy ModelEntityMapper

The XML

<!-- Interface -->
<reference id="modelEntityMapper" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />
<!-- Implementation defined within same bundle -->
<bean id="modelEntityMapperImpl" class="org.example.blog.rest.cxf.server.model.impl.ModelEntityMapperImpl" />

<!-- Object which has dependency -->
<bean id="posts" class="org.example.blog.rest.cxf.server.BlogResourceImpl">
        <property name="modelEntityMapper" ref="modelEntityMapperImpl" />
</bean>

The Log

Bundle rest-cxf-server is waiting for dependencies [(objectClass=org.example.blog.rest.cxf.server.model.ModelEntityMapper)]

도움이 되었습니까?

해결책 2

I was unable to find detailed documentation on the Aries site related to referencing in bundles, so I'm going to reference the Eclipse Gemini Blueprint implementation documentation (formerly Spring Dynamic Modules). See the warning in section 9.2.1.1 of their documentation. Yes, technically this is related to their implementation, but I believe it's likely a similar story in Aries.

It is an error to declare a mandatory reference to a service that is also exported by the same bundle, this behaviour can cause application context creation to fail through either deadlock or timeout.

In a nutshell you typically either import (reference) an OSGi service or you export an OSGi service in the same bundle, usually you don't try to do both in a single bundle.

If you want this bundle to export a service of type ModelEntityMapper, then you'll need to export it with the service element. When other beans need a reference within the same bundle, you would use the ref attribute like you're using it. In this case, you would not need the reference element at all, but instead use the service element.

If you're not going to use the ModelEntityMapper bean outside of this bundle, you don't need to use a reference or service element in the configuration at all. You should be able to use it in the ref attribute without exporting it as an OSGi service - it's basically a bean internal to that bundle. In this case, you should be able to remove the reference element altogether: the <bean id="modelEntityMapperImpl" ... will create a bean internal to the bundle, and the <property name="modelEntityMapper" ref="modelEntityMapperImpl" /> element should be able to use that bean internally to the bundle.

If you want to import a reference of type ModelEntityMapper from OSGi if available, else use an internally defined fallback, that gets more complicated. You'd have to declare a non-mandatory reference and inject that reference into your class along with the internally defined bean and then have defaulting logic that checks the availability of them. Alternatively you could just define the implementation in a separate bundle from the interface.

다른 팁

Can you just refer to the bean of the service directly? If you define the service and the service reference in the same blueprint file then using an OSGi service does not make that much sense.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top