bugfix> java > 投稿

次の汎用cglibメソッドインターセプター実装があります。

public class EntityInterceptor<T, PK> implements MethodInterceptor{
    private EntityChangeType changeType;
    private T entity;
    private GenericCrudMapper<T,PK> mapper;
    public EntityInterceptor(T entity, GenericCrudMapper<T, PK> mapper){
        this.entity = entity;
        this.mapper = mapper;
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // pass through
        return proxy.invoke(entity, args);
    }
    public void setEntityChangeType(EntityChangeType changeType){
        this.changeType = changeType;
    }
    public void saveChanges(){
        // @todo
    }
}

次のように使用されます:

@Override
    public Airport get(String id) {
        Airport airport = airportMapper.findById(id);
        if(airport != null){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Airport.class);
            enhancer.setCallback(new EntityInterceptor<>(airport, airportMapper));
            airport = (Airport) enhancer.create();
            return airport;
        }
        return airport;
    }

上記で作成したメソッドインターセプターが拡張クラスインスタンスごとにインスタンス化されると安全に想定できます(つまり、メソッドインターセプターを割り当てるとき、それらはすべてのクラスインスタンス間で共有されません)?

回答 1 件
  • はい、あなたはこれについて確信することができます。ただし、インスタンスごとに新しいクラスが生成されるため、ソリューションはかなり非効率的です。代わりに、インターセプタータイプに基づいてプロキシを作成する必要があります。

    // Do once
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(realObject.getClass());
    enhancer.setCallbackType(Airport.class);
    Class classForProxy = enhancer.createClass();
    // Do for each instance
    Enhancer.registerCallbacks(classForProxy, new Callback[]{new EntityInterceptor<>(airport, airportMapper});
    Object createdProxy = classForProxy.newInstance();
    
    

    このようにして、すべてのプロキシインスタンスに対して単一のクラスを再利用できます。

あなたの答え