首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在call()之前劫持Callable并执行隐藏方法

如何在call()之前劫持Callable并执行隐藏方法
EN

Stack Overflow用户
提问于 2011-06-30 02:38:04
回答 1查看 443关注 0票数 1

我正在向一个更大的项目(HypergraphDB)中的一些子系统添加实现,我应该避免修改重要的代码。在这个项目中,大约有70个可调用对象,它们定义了一些数据库操作的事务块。我正在替换那个数据库,而我的(redis)在定义事务块之前需要所有受影响的键。因此,我需要访问这些可调用函数中的部分,并在执行call()之前执行一些操作("watch")。

其中一些可调用函数非常重要,对于其中一些函数,我需要在可调用函数中声明最终字段,并在调用之外定义它们,以便call()和getHandles()都可以访问它们。

为了能够访问getHandles方法,我定义了一个只有getHandles方法的接口。要访问getHandles,我可以临时将Callable强制转换为该接口,在集成开发环境中它现在可以“看到”该方法,但我没有办法测试它。

这样行得通吗?

之前的代码:

代码语言:javascript
复制
       private HGLiveHandle addLink(final Object payload, 
                             final HGHandle typeHandle, 
                             final HGLink outgoingSet, 
                             final byte flags)
{
    return getTransactionManager().ensureTransaction(new Callable<HGLiveHandle>() 
    { public HGLiveHandle call() {
        HGAtomType type = typeSystem.getType(typeHandle);
        HGPersistentHandle pTypeHandle = getPersistentHandle(typeHandle);
        HGPersistentHandle valueHandle = TypeUtils.storeValue(HyperGraph.this, payload, type);            
......
}

代码如下:

代码语言:javascript
复制
         private HGLiveHandle addLink(final Object payload, 
                             final HGHandle typeHandle, 
                             final HGLink outgoingSet, 
                             final byte flags)
{
    return getTransactionManager().ensureTransaction(new Callable<HGLiveHandle>() 
    {

        final HGAtomType type = typeSystem.getType(typeHandle);
        final HGPersistentHandle pTypeHandle = getPersistentHandle(typeHandle);
        final HGPersistentHandle valueHandle = TypeUtils.storeValue(HyperGraph.this, payload, type);

        public HGPersistentHandle[] getHandles() {
               HGPersistentHandle[] result = new HGPersistentHandle[3+outgoingSet.getArity()];
           result[0] = atomHandle.getPersistent();
           result[1] = typeHandle.getPersistent();
           result[2] = valueHandle.getPersistent();
           result[3] = pTypeHandle;
           result[4] = .valueHandle;
           return result;
        }

        public HGLiveHandle call() {.........

可处理的接口:

代码语言:javascript
复制
     public interface Handable {

public HGPersistentHandle[] getHandles();

}

最后是它被调用的地方:

代码语言:javascript
复制
     public <V> V ensureTransaction(Callable<V> transaction, HGTransactionConfig config)
{
    if (getContext().getCurrent() != null)
        try 
        {
            for (HGPersistentHandle ph: ((Handable) transaction).getHandles());
            .... writeJedis.watch(ph.toByteArray);
            return transaction.call();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-30 03:07:21

如果您真的想截取可调用代码,而不想修改现有代码,那么最好的办法是在调用getTransactionManager()时换入不同的实现,因为这是您传递可调用代码的地方。

代码语言:javascript
复制
public class MyTransactionManager implements TransactionManager {

private final TransactionManager originalManager = ...;

public <V> V ensureTransaction(Callable<V> transaction, HGTransactionConfig config) {
    // Check for appropriate type
    if( transaction instanceof Handable) {
        for (HGPersistentHandle ph: ((Handable) transaction).getHandles()) {
            writeJedis.watch(ph.toByteArray);
        }
    }
    // Delegate to the original implementation
    return originalManager.ensureTransaction(transaction, config);
}

}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6525566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档