我目前正在开发一个 Sling servlet,它通过 Apache Felix 使用 OSGi 框架。据我了解,如果您想获取并使用其他服务,您有两种选择:
1. 编写一个服务监听器,确保在获取和使用您的服务之前注册您想要的服务。
2. 使用 Apache Felix 的 @Reference
注解获取服务。
我想做选项 2,因为选项 1 需要大量我不需要编写的代码。
所以,这就是我的做法。只是免责声明:以下是我的代码片段,并不构成我的整个项目。不要指望能够编译这个或任何东西。我已经包含了我认为相关的部分。
首先,我有我的 sling servlet:
package mypackage;
import /*necessary imports*/
@Component( name = "My Sling Servlet", immediate = false, metatype = true)
@Properties({
@Property(name = "sling.servlet.paths", value = "/bin/mytest"),
@Property(name = "sling.servlet.methods", value = "GET")
})
@Service(Servlet.class)
public class MyServlet extends SlingSafeMethodsServlet {
@Reference
private MyService service;
// Do stuff with service
}
据我了解,@Component
注释让OSGi知道这个类文件定义了一个组件。 @Properties
注释定义了组件的一些基本属性(在本例中,对我们来说重要的是现在我们可以通过转到 [hostname]/bin/mytest
来运行此 servlet)。 @Service
注释让 OSGi 知道该类是一个服务(特别是实现 Servlet 类的服务),并注册该服务。最后,@Reference 注释告诉 OSGi 我们要声明的字段是该 bundle 中已注册的 OSGi 服务,我们应该捕获它。
现在,这是另一个相关文件,它定义了服务 MyService:
package mypackage;
import /*necessary imports*/
@Component(name="MyService", immediate=false,metatype=true)
@Service(value = MyServiceInterface.class)
public class MyService implements MyServiceInterface {
// Implementation of MyServiceInterface
}
在这里,我们使用 @Component
注释声明 MyService 是一个 OSGi 组件。这里重要的一点是,我们使用了 @Service 注释,它显然完成了一项基本任务:@Service 注释注册服务。
请假设有一个文件 MyServiceInterface.java 看起来像这样:
package mypackage;
import /*necessary imports*/
public interface MyServiceInterface {
//stuff
}
完成所有这些预备工作后,这是我的问题。当我通过在 Web 浏览器中访问 [hostname]/bin/mytest
来运行 servlet 时,出现 404 页面未找到错误。这表明我的浏览器找不到该 servlet。
您现在可能会问自己,为什么我认为这与 @Reference
注释有某种关系。嗯,我认为这在某种程度上是负责任的,因为当我将其注释掉并以老式方式获取服务(即上面的方法 1)时,servlet 运行没有任何问题。
另一个可能相关的信息是我正在使用 Maven 来构建这个项目。如果您认为相关的 pom.xml 文件包含有用的信息,我很乐意提供它们。
请帮我弄清楚为什么当我使用@Reference
注释时找不到我的servlet!如果您需要我在帮助我之前提供更多信息,我很乐意这样做。如果我没有提供足够的信息,请在评论中指出。
提前致谢!
最佳答案
我总是做的第一件事就是检查我的包和 servlet 是否在 Apache Felix 控制台 http://localhost:8080/system/console/bundles 中处于 Activity 状态。和 http://localhost:8080/system/console/components 。您是否缺少任何依赖项,导致您的 bundle 或组件无法激活?
根据您的问题,我的第一个猜测是您可能没有使用 Apache Felix Maven SCR Plugin 。正如您所说,您不想手动创建 ServiceListeners(您指定的选项 1),而是希望使用声明式服务(您指定的选项 2),并且为此您需要 SCR 插件。 @Reference
等注释不是运行时的,SCR 插件使用它们来生成您的服务在具有声明性服务的 OSGi 环境中工作所需的代码和元数据。上面提供的文档链接详细介绍了该插件的功能。只需将插件添加到您的 pom.xml
文件中,如文档中所示:
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<version>1.20.0</version>
<executions>
<execution>
<id>generate-scr-scrdescriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
...
</project>
关于java - Apache Felix @Reference 注解问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37952560/