如何在公共池中使用aop

how to use aop in common-pool

我是 apache common 的新手 pool.I 使用 pool.borrowObject(); 从池中获取实例并在最后执行 pool.returnObject(obj); block.So 我想使用 aop instand将 finally 块写入 return 实例返回 pool.I 认为 spring aop 可以做到这一点,但如何获得实例 "obj"aop:after

public class ServiceImpl implements Service{

    private GenericObjectPool<Foo> pool;

    @Override
    public void insert() {
        try {
            Foo obj = pool.borrowObject();
            //do something
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            pool.returnObject(obj);
        }
    }

    public GenericObjectPool getPool() {
        return pool;
    }

    public void setPool(GenericObjectPool pool) {
        this.pool = pool;
    }
}

如果您需要访问方面内的对象

如果 ServiceImpl 具有 原型范围,您可以这样做

public class ServiceImpl implements Service{

private Foo obj;

@Override
public void insert() {
    . .....
        obj = pool.borrowObject();
    . .....
    return obj;
}

public Foo getFooObj(){
   return obj;
}

}

如果 ServiceImpl 有 单例作用域,你可以这样做

public class ServiceImpl implements Service{
private ThreadLocal serviceThreadLocal = new ThreadLocal();

@Override
public void insert() {
    . .....
        obj = pool.borrowObject();
        serviceThreadLocal.set(obj);
    . .....
    return obj;
}

public Foo getFooObj(){
   return serviceThreadLocal .get();
}
}

在这里您可以访问来自轮询的对象。


或者您在方面中设置/包装处理轮询逻辑

添加自定义注释:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplyObjectFromPool {
}

并更改一点实现:

@Component
public class ServiceImpl implements Service , HasObjectFromPool<Foo> {

    private Foo obj;

    @Override
    @ApplyObjectFromPool
    public void insert() {
        try {
            obj = getObjectFromPool();
            //do something
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Foo getObjectFromPool(){
        return obj;
    }

    @Override
    public void setObjectFromPool(Foo object) {
        this.obj=object;
    }
}

并配置切入点:

@Aspect
@Component
public class ObjectFromPoolAspect {
    private GenericObjectPool pool = new GenericObjectPool();

    @Around("within(org........HasObjectFromPool+) && @annotation(applyObjectFromPool))")
    public Object applyObjectFromPool(ProceedingJoinPoint point ,
                  ApplyObjectFromPool applyObjectFromPool) throws Throwable {
        Object result;
        HasObjectFromPool target = (HasObjectFromPool) point.getTarget();
        Object objectFromPool = pool.borrowObject();
        try {
            target.setObjectFromPool(objectFromPool);
            result = point.proceed();
        }finally {
            pool.returnObject(objectFromPool);
        }
        return result;
    }
}

恕我直言:如果您只使用池 ServiceImpl,请保持原样,如果您在几个不同的地方有相同的逻辑,这关于小型重构并使用 Template Method Pattern or Command Pattern。在你的情况下使用 aop 这是不好的方法。您应该更改代码以使其可用于方面而不是用于改进。