001/* 002 * Copyright 2002-2019 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.config; 018 019import org.springframework.lang.Nullable; 020import org.springframework.util.Assert; 021 022/** 023 * Immutable placeholder class used for a property value object when it's 024 * a reference to another bean in the factory, to be resolved at runtime. 025 * 026 * @author Rod Johnson 027 * @author Juergen Hoeller 028 * @see BeanDefinition#getPropertyValues() 029 * @see org.springframework.beans.factory.BeanFactory#getBean(String) 030 * @see org.springframework.beans.factory.BeanFactory#getBean(Class) 031 */ 032public class RuntimeBeanReference implements BeanReference { 033 034 private final String beanName; 035 036 @Nullable 037 private final Class<?> beanType; 038 039 private final boolean toParent; 040 041 @Nullable 042 private Object source; 043 044 045 /** 046 * Create a new RuntimeBeanReference to the given bean name. 047 * @param beanName name of the target bean 048 */ 049 public RuntimeBeanReference(String beanName) { 050 this(beanName, false); 051 } 052 053 /** 054 * Create a new RuntimeBeanReference to the given bean name, 055 * with the option to mark it as reference to a bean in the parent factory. 056 * @param beanName name of the target bean 057 * @param toParent whether this is an explicit reference to a bean in the 058 * parent factory 059 */ 060 public RuntimeBeanReference(String beanName, boolean toParent) { 061 Assert.hasText(beanName, "'beanName' must not be empty"); 062 this.beanName = beanName; 063 this.beanType = null; 064 this.toParent = toParent; 065 } 066 067 /** 068 * Create a new RuntimeBeanReference to a bean of the given type. 069 * @param beanType type of the target bean 070 * @since 5.2 071 */ 072 public RuntimeBeanReference(Class<?> beanType) { 073 this(beanType, false); 074 } 075 076 /** 077 * Create a new RuntimeBeanReference to a bean of the given type, 078 * with the option to mark it as reference to a bean in the parent factory. 079 * @param beanType type of the target bean 080 * @param toParent whether this is an explicit reference to a bean in the 081 * parent factory 082 * @since 5.2 083 */ 084 public RuntimeBeanReference(Class<?> beanType, boolean toParent) { 085 Assert.notNull(beanType, "'beanType' must not be empty"); 086 this.beanName = beanType.getName(); 087 this.beanType = beanType; 088 this.toParent = toParent; 089 } 090 091 092 /** 093 * Return the requested bean name, or the fully-qualified type name 094 * in case of by-type resolution. 095 * @see #getBeanType() 096 */ 097 @Override 098 public String getBeanName() { 099 return this.beanName; 100 } 101 102 /** 103 * Return the requested bean type if resolution by type is demanded. 104 * @since 5.2 105 */ 106 @Nullable 107 public Class<?> getBeanType() { 108 return this.beanType; 109 } 110 111 /** 112 * Return whether this is an explicit reference to a bean in the parent factory. 113 */ 114 public boolean isToParent() { 115 return this.toParent; 116 } 117 118 /** 119 * Set the configuration source {@code Object} for this metadata element. 120 * <p>The exact type of the object will depend on the configuration mechanism used. 121 */ 122 public void setSource(@Nullable Object source) { 123 this.source = source; 124 } 125 126 @Override 127 @Nullable 128 public Object getSource() { 129 return this.source; 130 } 131 132 133 @Override 134 public boolean equals(@Nullable Object other) { 135 if (this == other) { 136 return true; 137 } 138 if (!(other instanceof RuntimeBeanReference)) { 139 return false; 140 } 141 RuntimeBeanReference that = (RuntimeBeanReference) other; 142 return (this.beanName.equals(that.beanName) && this.beanType == that.beanType && 143 this.toParent == that.toParent); 144 } 145 146 @Override 147 public int hashCode() { 148 int result = this.beanName.hashCode(); 149 result = 29 * result + (this.toParent ? 1 : 0); 150 return result; 151 } 152 153 @Override 154 public String toString() { 155 return '<' + getBeanName() + '>'; 156 } 157 158}