1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.aop.framework;
  17. import java.lang.reflect.Method;
  18. import java.util.HashMap;
  19. import java.util.IdentityHashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import org.springframework.core.JdkVersion;
  23. /**
  24. * AdvisorChainFactory implementation that caches by method.
  25. *
  26. * <p>Uses java.util.IdentityHashMap on J2SE 1.4, which skips expensive
  27. * Method.hashCode() call. On J2SE 1.3, falls back to using java.util.HashMap.
  28. *
  29. * @author Rod Johnson
  30. * @version $Id: HashMapCachingAdvisorChainFactory.java,v 1.8 2004/06/02 20:44:07 jhoeller Exp $
  31. * @see java.util.IdentityHashMap
  32. * @see java.util.HashMap
  33. * @see java.lang.reflect.Method#hashCode
  34. */
  35. public final class HashMapCachingAdvisorChainFactory implements AdvisorChainFactory {
  36. private final Map methodCache = createMap();
  37. private Map createMap() {
  38. // Use IdentityHashMap, introduced in J2SE 1.4, which is a lot faster
  39. // as we want to compare Method keys by reference. If not available,
  40. // fall back to standard HashMap.
  41. if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_14) {
  42. return IdentityHashMapCreator.createIdentityHashMap();
  43. }
  44. else {
  45. return new HashMap();
  46. }
  47. }
  48. public List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Object proxy,
  49. Method method, Class targetClass) {
  50. List cached = (List) this.methodCache.get(method);
  51. if (cached == null) {
  52. // recalculate
  53. cached = AdvisorChainFactoryUtils.calculateInterceptorsAndDynamicInterceptionAdvice(config, proxy,
  54. method, targetClass);
  55. this.methodCache.put(method, cached);
  56. }
  57. return cached;
  58. }
  59. public void activated(AdvisedSupport advisedSupport) {
  60. }
  61. public void adviceChanged(AdvisedSupport advisedSupport) {
  62. this.methodCache.clear();
  63. }
  64. /**
  65. * Actual creation of a java.util.IdentityHashMap.
  66. * In separate inner class to avoid runtime dependency on JDK 1.4.
  67. */
  68. private static abstract class IdentityHashMapCreator {
  69. private static Map createIdentityHashMap() {
  70. return new IdentityHashMap();
  71. }
  72. }
  73. }