All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jdon.aop.interceptor.PoolInterceptor Maven / Gradle / Ivy

/*
 * 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;

	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy