3

我有一个 OSGi 捆绑包(不属于我 - 所以我无法更改它!),它公开(导出)一个服务EchoService,我想将一个方面附加到这个服务的方法(以便执行一些前/后处理周围)。这些部署在 Apache Felix 容器上。

我已经编写了自己的 OSGi 包(显然导入了EchoService),并使用标准 Spring AOP 将 Spring 方面附加到它。但是,看起来方面没有附加,并且我的拦截器没有被调用。

我怀疑这是因为我试图拦截一个不属于我的包的服务(这似乎是合理的)。那是对的吗?我该如何克服呢?

这是我的拦截器/方面的样子:

    @Before("serviceOperation()")
    public void before(JoinPoint jp) {
        logger.debug("Entering method: " + jp.toShortString());
    }

    @AfterReturning("serviceOperation()")
    public void after(JoinPoint jp) {       
        logger.debug("Exiting method: " + jp.toShortString());      
    }
4

1 回答 1

1

我不是 AOP 也不是 Spring 专家,但也许我可以给你一些想法。据我所知Spring 使用标准 J2SE 动态代理 AOP 代理。因此,您的客户应该使用代理而不是原始EchoService对象。当您使用 CGLIB 代理时也是如此,因为“代理是通过子类化实际类创建的”

如果您的客户捆绑要求EchoService您必须以某种方式将代理传递给他们。为此,您还应该在 OSGi 容器中导出一个EchoService(代理)并确保客户端使用代理服务/捆绑包,而不是原始服务/捆绑包。您可以通过为(代理)包设置不同的版本号并将此版本设置为客户端捆绑包中的导入要求来完成此操作。(我想您可以修改 . 的客户端EchoService。)对于服务,您可以在注册时设置一个属性并将客户端修改为仅查询具有此属性的服务。

如果您无法修改客户端捆绑包,另一种解决方案可能是将原始捆绑包包装为捆绑包中的内部 jar。您可以从您的激活器中调用包装捆绑包的激活器,并将其传递给修改后的BundleContext. 这BundleContext应该捕获注册服务调用并注册代理对象而不是原始的EchoService. 您可以使用简单的委托模式,因为BundleContextServiceListener通常是接口。我想它可以工作,但它可能还有其他挑战。

于 2011-09-25T17:18:26.087 回答