BeanFactory的本质是Factory,是SpringIOC的实现原理
比如AbstractBeanFactory就是实现BeanFactory的
FactoryBean的本质是个bean,不过这个bean的的目的是创建别的bean,目的是创建一些复杂的bean
public interface Guser {
void test();
}
public class GuserImpl implements Guser{
public GuserImpl() {
System.out.println("impl");
}
@Override
public void test() {
}
}
@Component
public class TestFactoryBean implements FactoryBean\<Guser> {
public TestFactoryBean() {
System.out.println("bean");
}
@Override
public Guser getObject() throws Exception {
//这里可以写一些复杂的处理逻辑
return new GuserImpl();
}
@Override
public Class<?> getObjectType() {
return Guser.class;
}
@Override
public boolean isSingleton() {
return true;
}
public void test(){
}
}
//得到一个Guser
Object o = applicationContext.getBean("testFactoryBean");
//得到一个TestFactoryBean
Object o1 = applicationContext.getBean(TestFactoryBean.class);
//得到一个Guser
Object o2 = applicationContext.getBean(Guser.class);
//报错
Object o3 = applicationContext.getBean("guser");
1、使用
@Autowired
private Guser guser;
时
创建bean需要给属性guser赋值
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
//赋值
element.inject(target, beanName, pvs);
}
}
}
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//找出来的是testFactoryBean
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = classObjectEntry.getValue();
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
//通过candidate找bean
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
......
}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//通过factoryBean的getObject
object = factory.getObject();
}
}
......
}
Object o2 = applicationContext.getBean(Guser.class);
实际是也是先找的"factoryBean"再找的Guser(factory.getObject)
通过Guser.class找"factoryBean"过程
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>();
// Check all bean definitions.
//要校验所有的bean
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
// In case of FactoryBean, match object created by FactoryBean.
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
boolean matchFound =
(allowEagerInit || !isFactoryBean ||
(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
(includeNonSingletons ||
(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
isTypeMatch(beanName, type);
if (!matchFound && isFactoryBean) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
}
if (matchFound) {
result.add(beanName);
}
}
}
catch (CannotLoadBeanClassException ex) {
if (allowEagerInit) {
throw ex;
}
// Probably a class name with a placeholder: let's ignore it for type matching purposes.
if (logger.isTraceEnabled()) {
logger.trace("Ignoring bean class loading failure for bean '" + beanName + "'", ex);
}
onSuppressedException(ex);
}
catch (BeanDefinitionStoreException ex) {
if (allowEagerInit) {
throw ex;
}
// Probably some metadata with a placeholder: let's ignore it for type matching purposes.
if (logger.isTraceEnabled()) {
logger.trace("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex);
}
onSuppressedException(ex);
}
}
}
// Check manually registered singletons too.
for (String beanName : this.manualSingletonNames) {
try {
// In case of FactoryBean, match object created by FactoryBean.
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// In case of FactoryBean, try to match FactoryBean itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Shouldn't happen - probably a result of circular reference resolution...
if (logger.isTraceEnabled()) {
logger.trace("Failed to check manually registered singleton with name '" + beanName + "'", ex);
}
}
}
return StringUtils.toStringArray(result);
}
三级缓存外,还有一个缓存
使用FactoryBean的名字,实际是具体的bean
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);