001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.component.bean; 018 019import java.lang.reflect.Method; 020import java.util.Map; 021 022import org.apache.camel.CamelContext; 023import org.apache.camel.util.LRUSoftCache; 024 025/** 026 * Represents a cache of {@link MethodInfo} objects to avoid the expense of introspection for each 027 * invocation of a method via a proxy. 028 * 029 * @version 030 */ 031public class MethodInfoCache { 032 private final CamelContext camelContext; 033 private Map<Method, MethodInfo> methodCache; 034 private Map<Class<?>, BeanInfo> classCache; 035 036 public MethodInfoCache(CamelContext camelContext) { 037 this(camelContext, 1000, 10000); 038 } 039 040 public MethodInfoCache(CamelContext camelContext, int classCacheSize, int methodCacheSize) { 041 this(camelContext, createClassCache(classCacheSize), createMethodCache(methodCacheSize)); 042 } 043 044 public MethodInfoCache(CamelContext camelContext, Map<Class<?>, BeanInfo> classCache, Map<Method, MethodInfo> methodCache) { 045 this.camelContext = camelContext; 046 this.classCache = classCache; 047 this.methodCache = methodCache; 048 } 049 050 public synchronized MethodInfo getMethodInfo(Method method) { 051 MethodInfo answer = methodCache.get(method); 052 if (answer == null) { 053 answer = createMethodInfo(method); 054 methodCache.put(method, answer); 055 } 056 return answer; 057 } 058 059 protected MethodInfo createMethodInfo(Method method) { 060 Class<?> declaringClass = method.getDeclaringClass(); 061 BeanInfo info = getBeanInfo(declaringClass); 062 return info.getMethodInfo(method); 063 } 064 065 protected synchronized BeanInfo getBeanInfo(Class<?> declaringClass) { 066 BeanInfo beanInfo = classCache.get(declaringClass); 067 if (beanInfo == null) { 068 beanInfo = createBeanInfo(declaringClass); 069 classCache.put(declaringClass, beanInfo); 070 } 071 return beanInfo; 072 } 073 074 protected BeanInfo createBeanInfo(Class<?> declaringClass) { 075 return new BeanInfo(camelContext, declaringClass); 076 } 077 078 protected static <K, V> Map<K, V> createLruCache(int size) { 079 // use a soft cache 080 return new LRUSoftCache<K, V>(size); 081 } 082 083 private static Map<Class<?>, BeanInfo> createClassCache(int size) { 084 return createLruCache(size); 085 } 086 087 private static Map<Method, MethodInfo> createMethodCache(int size) { 088 return createLruCache(size); 089 } 090}