如何在公共池中使用aop

时间:2017-07-12 05:53:31

标签: java spring-aop pool

我是apache公共池的新手。我使用pool.borrowObject();从池中获取实例并在finally块中执行pool.returnObject(obj);。所以我想使用aop instand编写finally块来将instane返回pool。我认为spring aop可以做到这一点,但是如何在 aop中获取实例“obj”

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;
    }
}

1 个答案:

答案 0 :(得分:0)

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

如果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 Command Pattern。在你的情况下使用aop它是不好的方法。您应该更改代码,使其可用于方面而不是改进。