在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的实现原理剖析完结。