com.jdon.aop.interceptor.PoolInterceptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jdonframework Show documentation
Show all versions of jdonframework Show documentation
JdonFramework is a java framework that you can use to build your Domain Driven Design + CQRS + EventSource applications with asynchronous concurrency and higher throughput.
/*
* Copyright 2003-2006 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jdon.aop.interceptor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.pool.impl.GenericObjectPool;
import com.jdon.aop.reflection.ProxyMethodInvocation;
import com.jdon.bussinessproxy.TargetMetaDef;
import com.jdon.bussinessproxy.target.TargetServiceFactory;
import com.jdon.container.ContainerWrapper;
import com.jdon.container.access.TargetMetaRequestsHolder;
import com.jdon.container.finder.ComponentKeys;
import com.jdon.container.finder.ContainerCallback;
import com.jdon.container.pico.Startable;
import com.jdon.controller.cache.InstanceCache;
import com.jdon.controller.pool.CommonsPoolAdapter;
import com.jdon.controller.pool.CommonsPoolFactory;
import com.jdon.controller.pool.Pool;
import com.jdon.controller.pool.PoolConfigure;
import com.jdon.controller.pool.Poolable;
import com.jdon.util.Debug;
/**
* PoolInterceptor must be the last in Interceptors. this class is active for
* the pojoServices that implements com.jdon.controller.pool.Poolable.
*
* @author banq
*
*/
public class PoolInterceptor implements MethodInterceptor, Startable {
private final static String module = PoolInterceptor.class.getName();
/**
* one target object, one pool
*/
private Map poolFactorys;
private TargetServiceFactory targetServiceFactory;
private ContainerCallback containerCallback;
private PoolConfigure poolConfigure;
private List isPoolableCache = new CopyOnWriteArrayList();
private List unPoolableCache = new ArrayList();
private TargetMetaRequestsHolder targetMetaRequestsHolder;
/**
* @param containerCallback
*/
public PoolInterceptor(TargetServiceFactory targetServiceFactory, TargetMetaRequestsHolder targetMetaRequestsHolder,
ContainerCallback containerCallback, PoolConfigure poolConfigure) {
super();
this.targetServiceFactory = targetServiceFactory;
this.targetMetaRequestsHolder = targetMetaRequestsHolder;
this.containerCallback = containerCallback;
this.poolConfigure = poolConfigure;
this.poolFactorys = new HashMap();
}
/*
* (non-Javadoc)
*
* @see
* org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept
* .MethodInvocation)
*/
public Object invoke(MethodInvocation invocation) throws Throwable {
ProxyMethodInvocation proxyMethodInvocation = (ProxyMethodInvocation) invocation;
TargetMetaDef targetMetaDef = targetMetaRequestsHolder.getTargetMetaRequest().getTargetMetaDef();
if (targetMetaDef.isEJB())
return invocation.proceed();
if (!isPoolabe(targetMetaDef)) {
// Debug.logVerbose("[JdonFramework] target service is not Poolable: "
// + targetMetaDef.getClassName() + " pool unactiive", module);
return invocation.proceed(); // 下一个interceptor
}
Debug.logVerbose("[JdonFramework] enter PoolInterceptor", module);
CommonsPoolFactory commonsPoolFactory = (CommonsPoolFactory) poolFactorys.get(targetMetaDef.getCacheKey());
if (commonsPoolFactory == null) {
commonsPoolFactory = getCommonsPoolFactory(targetMetaDef);
poolFactorys.put(targetMetaDef.getCacheKey(), commonsPoolFactory);
}
Pool pool = commonsPoolFactory.getPool();
Object poa = null;
Object result = null;
try {
poa = pool.acquirePoolable();
Debug.logVerbose("[JdonFramework] borrow a object:" + targetMetaDef.getClassName() + " id:" + poa.hashCode() + " from pool", module);
Debug.logVerbose("[JdonFramework]pool state: active=" + pool.getNumActive() + " free=" + pool.getNumIdle(), module);
// set the object that borrowed from pool to MethodInvocation
// so later other Interceptors or MethodInvocation can use it!
proxyMethodInvocation.setThis(poa);
result = invocation.proceed();
} catch (Exception ex) {
Debug.logError(ex, module);
} finally {
if (poa != null) {
pool.releasePoolable(poa);
Debug.logVerbose("[JdonFramework] realease a object:" + targetMetaDef.getClassName() + " to pool", module);
}
}
return result;
}
/**
* every target service has its CommonsPoolFactory, we cache it in
* container, next time, we can get the cached Object Pool for the target
* service;
*
* @param targetMetaDef
* @return
*/
private CommonsPoolFactory getCommonsPoolFactory(TargetMetaDef targetMetaDef) {
CommonsPoolFactory commonsPoolFactory = null;
try {
ContainerWrapper containerWrapper = containerCallback.getContainerWrapper();
InstanceCache instanceCache = (InstanceCache) containerWrapper.lookup(ComponentKeys.INSTANCE_CACHE);
String key = targetMetaDef.getCacheKey() + " CommonsPoolFactory";
commonsPoolFactory = (CommonsPoolFactory) instanceCache.get(key);
if (commonsPoolFactory == null) {
Debug.logVerbose("[JdonFramework] first time call commonsPoolFactory, create it:" + key, module);
commonsPoolFactory = create(targetServiceFactory, poolConfigure.getMaxPoolSize());
instanceCache.put(key, commonsPoolFactory);
}
} catch (Exception ex) {
Debug.logError(ex, module);
}
return commonsPoolFactory;
}
public CommonsPoolFactory create(TargetServiceFactory targetServiceFactory, String maxSize) {
CommonsPoolFactory commonsPoolFactory = new CommonsPoolFactory(targetServiceFactory, maxSize);
GenericObjectPool apachePool = new GenericObjectPool(commonsPoolFactory);
CommonsPoolAdapter pool = new CommonsPoolAdapter(apachePool);
if (maxSize == null) {
Debug.logError("[JdonFramework] not set pool's max size", module);
} else {
int maxInt = Integer.parseInt(maxSize);
pool.setMaxPoolSize(maxInt);
}
commonsPoolFactory.setPool(pool);
return commonsPoolFactory;
}
public boolean isPoolabe(TargetMetaDef targetMetaDef) {
boolean found = false;
if (isPoolableCache.contains(targetMetaDef.getName())) {
found = true;
} else if (!unPoolableCache.contains(targetMetaDef.getName())) {
Debug.logVerbose("[JdonFramework] check if it is a Poolable", module);
ContainerWrapper containerWrapper = containerCallback.getContainerWrapper();
Class thisCLass = containerWrapper.getComponentClass(targetMetaDef.getName());
if (Poolable.class.isAssignableFrom(thisCLass) || thisCLass.isAnnotationPresent(com.jdon.annotation.intercept.Poolable.class)) {
found = true;
isPoolableCache.add(targetMetaDef.getName());
} else {
unPoolableCache.add(targetMetaDef.getName());
}
}
return found;
}
@Override
public void start() {
// TODO Auto-generated method stub
}
@Override
public void stop() {
if (this.isPoolableCache != null) {
this.isPoolableCache.clear();
this.unPoolableCache.clear();
this.poolFactorys.clear();
this.targetMetaRequestsHolder.clear();
}
ContainerWrapper containerWrapper = containerCallback.getContainerWrapper();
InstanceCache instanceCache = (InstanceCache) containerWrapper.lookup(ComponentKeys.INSTANCE_CACHE);
if (instanceCache != null)
for (Object key : instanceCache.keys()) {
if (key instanceof String) {
CommonsPoolFactory commonsPoolFactory = (CommonsPoolFactory) instanceCache.get((String) key);
commonsPoolFactory.getPool().close();
}
}
this.containerCallback = null;
this.isPoolableCache = null;
this.poolConfigure = null;
this.poolFactorys = null;
this.targetMetaRequestsHolder = null;
this.targetServiceFactory = null;
this.unPoolableCache = null;
}
}