在spring中,如果一个bean的创立过程很简单,咱们能够应用FactoryBean。
比方像上面的状况,我定义一套webService框架。

public interface WebService {    void service();  }public class DefaultWebService implements WebService {    private String serviceName;    public DefaultWebService(String serviceName) {        this.serviceName = serviceName;    }    @Override    public void service() {        System.out.println(serviceName + ": current support service  for  you....");    }}public class WebServiceWrapper implements WebService {    private WebService webService;    public WebServiceWrapper(WebService webService) {        this.webService = webService;    }    @Override    public void service() {        System.out.println("befor service, we need do something....");        webService.service();    }}

WebService接口定义服务的规范,DefaultWebService是一个默认实现,WebServiceWrapper的次要作用是在理论服务之前,做一些查看,筹备等工作。
因而当咱们应用WebService,实际上是心愿应用的是WebServiceWrapper。

当初webService框架实现好了,并打包进去了,当初我须要在我的项目中利用应用spring注解个性去应用。

那该怎么办呢?我能够实现spring提供的FactoryBean接口,就像上面这样:

@Componentpublic class WebServiceFactoryBean implements FactoryBean {    @Override    public boolean isSingleton() {        return true;    }    @Override    public Object getObject() throws Exception {        return this.createWebService();    }    @Override    public Class<?> getObjectType() {        return WebService.class;    }    private Object createWebService() {        DefaultWebService webService = new DefaultWebService("Backend Service");        // create a proxy        WebServiceWrapper webServiceWrapper = new WebServiceWrapper(webService);        return webServiceWrapper;    }}

紧接着,就能够利用spring的性能去应用了

@RestControllerpublic class TestController {    @Autowired    private WebService webService;    @GetMapping(value = "webService")    public void webService() {        webService.service();    }}

http://localhost:8080/webService,控制台会输入:
befor service, we need do something....
Backend Service: current support service for you....

通过输入咱们晓得,该webService,注入的应该是WebServiceWrapper。
这里的次要疑难是,咱们应用@Component托管spring的bean是WebServiceFactoryBean。然而最初在TestController中,WebServiceWrapper的相干信息,只有是怎么被注入的呢?也就是spring是怎么利用FactoryBean来实现特定bean工厂的呢?

spring托管一个bean大略的流程是:
bean信息扫描->实例化->依赖注入->初始化

首先看下bean扫描阶段,在所有扫描进去的BeanDefinition中,没有发现WebServiceWrapper的相干信息,只有WebServiceFactoryBean的相干信息。所以spring不是在扫描阶段解析出WebServiceFactoryBean相干信息的。

再看下WebServiceFactoryBean的实例化过程:

    public void preInstantiateSingletons() throws BeansException {    // Trigger initialization of all non-lazy singleton beans...        for (String beanName : beanNames) {            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {                if (isFactoryBean(beanName)) {                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);                   }                else {                    getBean(beanName);                }            }        }    }

这段源码中,有个判断是说如果以后bean是FactoryBean,那么获取该FactoryBean自身时,beanName要加上一个非凡的前缀“&”。因为WebServiceFactoryBean是一个FactoryBean,所以此时调用的是:Object bean = getBean(FACTORY_BEAN_PREFIX + beanName),入参是:&webServiceFactoryBean
spring中getBean会去调用doGetBean():

    protected <T> T doGetBean(            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)            throws BeansException {// Create bean instance.                if (mbd.isSingleton()) {                    sharedInstance = getSingleton(beanName, () -> {                        try {                            return createBean(beanName, mbd, args);                        }                        catch (BeansException ex) {                            // Explicitly remove instance from singleton cache: It might have been put there                            // eagerly by the creation process, to allow for circular reference resolution.                            // Also remove any beans that received a temporary reference to the bean.                            destroySingleton(beanName);                            throw ex;                        }                    });                    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);                }}

先创立一个bean实例,而后通过getObjectForBeanInstance()返回一个实例。
这里疑难是,我明明都创立好了一个实例,我间接返回不就好了吗,为什么还要通过getObjectForBeanInstance()返回呢?上面看看该办法得形容:

/**获取给定bean实例的对象,能够是bean实例自身,也能够是FactoryBean所创立的对象。*/protected Object getObjectForBeanInstance(            Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// 判断beanName是否以FactoryBean "&"非凡前缀结尾,如果是以"&"结尾// 阐明以后获取的是FactoryBean自身if (BeanFactoryUtils.isFactoryDereference(name)) {            if (beanInstance instanceof NullBean) {                return beanInstance;            }            if (!(beanInstance instanceof FactoryBean)) {                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());            }            if (mbd != null) {                mbd.isFactoryBean = true;            }            return beanInstance;        }    // 如果该bean不是FactoryBean那么间接返回    if (!(beanInstance instanceof FactoryBean)) {            return beanInstance;        }    // 否则就利用FactoryBean返回该bean    Object object = null;        if (mbd != null) {            mbd.isFactoryBean = true;        }        else {            object = getCachedObjectForFactoryBean(beanName);        }        if (object == null) {            // Return bean instance from factory.            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;            // Caches object obtained from FactoryBean if it is a singleton.            if (mbd == null && containsBeanDefinition(beanName)) {                mbd = getMergedLocalBeanDefinition(beanName);            }            boolean synthetic = (mbd != null && mbd.isSynthetic());            object = getObjectFromFactoryBean(factory, beanName, !synthetic);        }        return object;}

下面的逻辑也是很清晰了,最初看下

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {Object object = doGetObjectFromFactoryBean(factory, beanName);            if (shouldPostProcess) {                try {                    object = postProcessObjectFromFactoryBean(object, beanName);                }                catch (Throwable ex) {                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);                }            }            return object;}private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, 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 {                **object = factory.getObject();**            }        }        catch (FactoryBeanNotInitializedException ex) {            throw new BeanCurrentlyInCreationException(beanName, ex.toString());        }        catch (Throwable ex) {            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);        }        // Do not accept a null value for a FactoryBean that's not fully        // initialized yet: Many FactoryBeans just return null then.        if (object == null) {            if (isSingletonCurrentlyInCreation(beanName)) {                throw new BeanCurrentlyInCreationException(                        beanName, "FactoryBean which is currently in creation returned null from getObject");            }            object = new NullBean();        }        return object;    }

其实就是调用了FactoryBean的getObject()返回该bean的。

通过下面的剖析,WebServiceFactoryBean是一个FactoryBean,
getBean("&webServiceFactoryBean"),此时spring中会创立一个WebServiceFactoryBean实例,而且返回也是WebServiceFactoryBean实例自身。因而spring容器还利用不到WebServiceFactoryBean的getObject()来返回WebService相干实例。

那么spring是在什么时候去调用getBean("webServiceFactoryBean"),而后利用WebServiceFactoryBean的getObject()来返回WebServiceWrapper的呢?

咱们仅仅晓得的是TestController依赖了WebService,依据后面提到spring托管bean的流程,TestController在依赖注入的时候,肯定会找到WebServiceWrapper!!!上面咱们依据这个思路去debug剖析下源码:

上面看下TestController的依赖注入阶段:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)            throws BeanCreat    BeanWrapper instanceWrapper = null;      // Initialize the bean instance.        Object exposedObject = bean;        try {            populateBean(beanName, mbd, instanceWrapper);            exposedObject = initializeBean(beanName, exposedObject, mbd);        }}

一个bean依赖注入的入口办法就是populateBean():

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {                PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);}}

InstantiationAwareBeanPostProcessor 是一个bean的实例化解决接口,
postProcessProperties()次要目标是对实例的属性进行解决。
其中有一个实现类:AutowiredAnnotationBeanPostProcessor就是用来实现依赖注入的。大略看下该类上的正文和结构器:

/**主动连贯正文字段、setter办法和任意配置办法的BeanPostProcessor实现。这些要注入的成员是通过正文检测的:默认状况下,是Spring的@Autowired和@Value正文。还反对JSR-330的@Inject正文(如果可用的话),作为Spring本人的@Autowired的间接代替。*/public AutowiredAnnotationBeanPostProcessor() {        this.autowiredAnnotationTypes.add(Autowired.class);        this.autowiredAnnotationTypes.add(Value.class);        try {            this.autowiredAnnotationTypes.add((Class<? extends Annotation>)                    ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));            logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");        }        catch (ClassNotFoundException ex) {            // JSR-330 API not available - simply skip.        }    }

其实就是咱们我的项目中应用的@Autowired,@Value等注入的实现形式。autowiredAnnotationTypes指定了反对哪些注解。

上面看下AutowiredAnnotationBeanPostProcessor的postProcessProperties():

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {        // 找到须要注入的字段        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);        try {            // 对每个字段进行注入          metadata.inject(bean, beanName, pvs);        }        catch (BeanCreationException ex) {            throw ex;        }        catch (Throwable ex) {            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);        }        return pvs;    }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) {                // 对每个依赖字段进行注入                element.inject(target, beanName, pvs);            }        }    }

对于TestController来说,只有一个WebService字段须要注入,因而会只有一个InjectedElement要进行inject。InjectedElement有两个实现类AutowiredFieldElement和AutowiredMethodElement。因为咱们这里是字段注入,所以看看AutowiredFieldElement的inject();

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {            // 以后要注入的字段是什么            Field field = (Field) this.member;            // 给该字段赋值的值到底是什么?            Object value;            if (this.cached) {                try {                    value = resolvedCachedArgument(beanName, this.cachedFieldValue);                }                catch (NoSuchBeanDefinitionException ex) {                    // Unexpected removal of target bean for cached argument -> re-resolve                    value = resolveFieldValue(field, bean, beanName);                }            }            else {                // 依据该字段信息,解析出value                value = resolveFieldValue(field, bean, beanName);            }            if (value != null) {                // 如果解析进去的值不为空,那么就进行赋值                ReflectionUtils.makeAccessible(field);                field.set(bean, value);            }        }

对于TestController,field天然是webService,这里的值,应该是webService的一个具体对象,然而显著还没有cached,因而要进行解析:

    private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {DependencyDescriptor desc = new DependencyDescriptor(field, this.required);            desc.setContainingClass(bean.getClass());            Set<String> autowiredBeanNames = new LinkedHashSet<>(1);            Assert.state(beanFactory != null, "No BeanFactory available");            TypeConverter typeConverter = beanFactory.getTypeConverter();            Object value;            try {                value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);            }return value;}public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {        descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());        if (Optional.class == descriptor.getDependencyType()) {            return createOptionalDependency(descriptor, requestingBeanName);        }        else if (ObjectFactory.class == descriptor.getDependencyType() ||                ObjectProvider.class == descriptor.getDependencyType()) {            return new DependencyObjectProvider(descriptor, requestingBeanName);        }        else if (javaxInjectProviderClass == descriptor.getDependencyType()) {            return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);        }        else {            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(                    descriptor, requestingBeanName);            if (result == null) {//  解析value                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);            }            return result;        }    }    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {    // 这里十分要害,实际上就是依据以后field,获取它的类型是什么!!!    Class<?> type = descriptor.getDependencyType();// 依据类型去找到对应的候选者Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);}    protected Map<String, Object> findAutowireCandidates(            @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(                this, requiredType, true, descriptor.isEager());}

doResolveDependency()办法中,有个关键点,那就java的Field提供了以后Field的java类型是什么。spring利用了这一点,而后依据类型去找到候选者!!!
此时type=WebService.class

一路debug,在findAutowireCandidates()办法中,发现candidateNames中呈现了,webServiceFactoryBean,也就是说spring把webServiceFactoryBean当作了一个WebService.其实大略测试也晓得是因为WebServiceFactoryBean的getObjectType()返回了WebService.class和要依赖注入的字段相匹配。

因而要害的代码是:

    public static String[] beanNamesForTypeIncludingAncestors(            ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {// 依据WebService.class去找到候选者的beanString[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);}    @Override    public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {String[] resolvedBeanNames = cache.get(type);        if (resolvedBeanNames != null) {            return resolvedBeanNames;        }        resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);return resolvedBeanNames;}    private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {List<String> result = new ArrayList<>();    // Check all bean definitions.        for (String beanName : this.beanDefinitionNames) {boolean isFactoryBean = isFactoryBean(beanName, mbd);                        BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();                        boolean matchFound = false;                        boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));                        boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());                        if (!isFactoryBean) {                            if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {                                matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);                            }                        }                        else {                            if (includeNonSingletons || isNonLazyDecorated ||                                    (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {                                matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);                            }                            if (!matchFound) {                                // In case of FactoryBean, try to match FactoryBean instance itself next.                                beanName = FACTORY_BEAN_PREFIX + beanName;                                if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {                                    matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);                                }                            }                        }                        if (matchFound) {                            result.add(beanName);                        }  }}    protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit)            throws NoSuchBeanDefinitionException {if (beanInstance instanceof FactoryBean) {                if (!isFactoryDereference) {                    Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);                    return (type != null && typeToMatch.isAssignableFrom(type));                }                else {                    return typeToMatch.isInstance(beanInstance);                }            }}protected Class<?> getTypeForFactoryBean(FactoryBean<?> factoryBean) {        try {            if (System.getSecurityManager() != null) {                return AccessController.doPrivileged(                        (PrivilegedAction<Class<?>>) factoryBean::getObjectType, getAccessControlContext());            }            else {                return factoryBean.getObjectType();            }        }        catch (Throwable ex) {            // Thrown from the FactoryBean's getObjectType implementation.            logger.info("FactoryBean threw exception from getObjectType, despite the contract saying " +                    "that it should return null if the type of its object cannot be determined yet", ex);            return null;        }    }

在匹配的过程中,如果一个bean是FactoryBean,那么就去查看它的getObjectType()返回的类型是否匹配。对于TestController来说,它的成员字段webService是WebService类型,于是spring会去容器中找,恰好WebServiceFactoryBean的getObjectType()返回就是WebService类型,于是匹配。

在下面doResolveDependency()中的 findAutowireCandidates()返回了一个WebServiceFactoryBean作为匹配的bean,然而还并没有返回须要注入的value,上面接着看doResolveDependency()

public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {            String autowiredBeanName;            Object instanceCandidate;String autowiredBeanName;            Object instanceCandidate;            if (matchingBeans.size() > 1) {                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);                if (autowiredBeanName == null) {                    if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {                        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);                    }                    else {                        // In case of an optional Collection/Map, silently ignore a non-unique case:                        // possibly it was meant to be an empty collection of multiple regular beans                        // (before 4.3 in particular when we didn't even look for collection beans).                        return null;                    }                }                instanceCandidate = matchingBeans.get(autowiredBeanName);            }            else {                // We have exactly one match.                Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();                autowiredBeanName = entry.getKey();                instanceCandidate = entry.getValue();            }            if (autowiredBeanNames != null) {                autowiredBeanNames.add(autowiredBeanName);            }            if (instanceCandidate instanceof Class) {                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);            }            Object result = instanceCandidate;return result;}

matchingBeans 目前的只蕴含一个key-value,其中key是webServiceFactoryBean,value则是WebServiceFactoryBean.class。因而真正的value是来自于下面的
descriptor.resolveCandidate()办法:

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)            throws BeansException {        return beanFactory.getBean(beanName);    }

这里留神到到,传入的beanName是webServiceFactoryBean!!!这一下子联想到后面说的,spring对于获取FactoryBean自身必须要对beanName加一个非凡的前缀。否则。。。否则就不是返回它本人啦,不必跟踪源码,咱们也可能大略猜得到,对于FactoryBean如果beanName不加非凡前缀返回的bean,是调用FactoryBean的getObject()办法返回的!!!联合后面的源码,的确如此。到此FactoryBean的实现原理剖析完结。