001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.factory.support; 018 019import java.lang.reflect.Method; 020 021import org.springframework.beans.BeanMetadataElement; 022import org.springframework.lang.Nullable; 023import org.springframework.util.Assert; 024import org.springframework.util.ObjectUtils; 025 026/** 027 * Object representing the override of a method on a managed object by the IoC 028 * container. 029 * 030 * <p>Note that the override mechanism is <em>not</em> intended as a generic 031 * means of inserting crosscutting code: use AOP for that. 032 * 033 * @author Rod Johnson 034 * @author Juergen Hoeller 035 * @author Sam Brannen 036 * @since 1.1 037 */ 038public abstract class MethodOverride implements BeanMetadataElement { 039 040 private final String methodName; 041 042 private boolean overloaded = true; 043 044 @Nullable 045 private Object source; 046 047 048 /** 049 * Construct a new override for the given method. 050 * @param methodName the name of the method to override 051 */ 052 protected MethodOverride(String methodName) { 053 Assert.notNull(methodName, "Method name must not be null"); 054 this.methodName = methodName; 055 } 056 057 058 /** 059 * Return the name of the method to be overridden. 060 */ 061 public String getMethodName() { 062 return this.methodName; 063 } 064 065 /** 066 * Set whether the overridden method is <em>overloaded</em> (i.e., whether argument 067 * type matching needs to occur to disambiguate methods of the same name). 068 * <p>Default is {@code true}; can be switched to {@code false} to optimize 069 * runtime performance. 070 */ 071 protected void setOverloaded(boolean overloaded) { 072 this.overloaded = overloaded; 073 } 074 075 /** 076 * Return whether the overridden method is <em>overloaded</em> (i.e., whether argument 077 * type matching needs to occur to disambiguate methods of the same name). 078 */ 079 protected boolean isOverloaded() { 080 return this.overloaded; 081 } 082 083 /** 084 * Set the configuration source {@code Object} for this metadata element. 085 * <p>The exact type of the object will depend on the configuration mechanism used. 086 */ 087 public void setSource(@Nullable Object source) { 088 this.source = source; 089 } 090 091 @Override 092 @Nullable 093 public Object getSource() { 094 return this.source; 095 } 096 097 /** 098 * Subclasses must override this to indicate whether they <em>match</em> the 099 * given method. This allows for argument list checking as well as method 100 * name checking. 101 * @param method the method to check 102 * @return whether this override matches the given method 103 */ 104 public abstract boolean matches(Method method); 105 106 107 @Override 108 public boolean equals(@Nullable Object other) { 109 if (this == other) { 110 return true; 111 } 112 if (!(other instanceof MethodOverride)) { 113 return false; 114 } 115 MethodOverride that = (MethodOverride) other; 116 return (ObjectUtils.nullSafeEquals(this.methodName, that.methodName) && 117 ObjectUtils.nullSafeEquals(this.source, that.source)); 118 } 119 120 @Override 121 public int hashCode() { 122 int hashCode = ObjectUtils.nullSafeHashCode(this.methodName); 123 hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.source); 124 return hashCode; 125 } 126 127}