Spring中这两个对象ObjectFactory与FactoryBean接口你使用过吗?( 二 )

这里的RequestObjectFactory , ResponseObjectFactory , SessionObjectFactory , WebRequestObjectFactory都是ObjectFactory接口 。
这几个接口实际获取的对象都是从当前线程的上下文中获取的(通过ThreadLocal) , 所以在Controller中直接属性注入相应的对象是线程安全的 。
注意:这里registerResolvableDependency方法意图就是当有Bean需要注入相应的Request , Response对象时直接注入第二个参数的值即可 。
2.3 自定义定义ObjectFactory在IOC容器 , 如果有两个相同类型的Bean , 这时候在注入的时候肯定是会报错的 , 示例如下:
public interface AccountDAO {}@Componentpublic class AccountADAO implements AccountDAO {}@Componentpublic class AccountBDAO implements AccountDAO {}@RestController@RequestMapping("/accounts")public class AccountController {@Resourceprivate AccountDAO dao ;}当我们有如上的Bean后 , 启动容器会报错如下:
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.pack.objectfactory.AccountDAO' avAIlable: expected single matching bean but found 2: accountADAO,accountBDAOat org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.JAVA:220) ~[spring-beans-5.2.13.RELEASE.jar:5.2.13.RELEASE]期望一个AccountDAO类型的Bean , 但当前环境却有两个 。
解决这个办法可以通过@Primary和@Qualifier来解决 , 这两个方法这里不做介绍;接下来我们通过BeanFactory#registerResolvableDependency的方式来解决;
自定义BeanFactoryPostProcessor
// 方式1:直接通过beanFactory获取指定的bean注入 。@Componentpublic class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// beanFactory的实例是DefaultListableBeanFactory , 该实例内部维护了一个ConcurrentMap resolvableDependencies 的集合 , Class作为key 。beanFactory.registerResolvableDependency(AccountDAO.class, beanFactory.getBean("accountBDAO"));}}自定义ObjectFactory
public class AccountObjectFactory implements ObjectFactory<AccountDAO> {@Overridepublic AccountDAO getObject() throws BeansException {return new AccountBDAO() ;}}// 对应的BeanFactoryPostProcessorbeanFactory.registerResolvableDependency(AccountDAO.class, new AccountObjectFactory());当一个Bean的属性在填充(注入)时调用AbstractAutowireCapableBeanFactory.populateBean方法时 , 会在当前的IOC容器中查找符合的Bean , 最终执行如下方法:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {protected Map<String, Object> findAutowireCandidates(@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {// 从当前IOC容器中查找所有指定类型的BeanString[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);// 遍历DefaultListableBeanFactory对象中通过registerResolvableDependency方法注册的for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {Class<?> autowiringType = classObjectEntry.getKey();if (autowiringType.isAssignableFrom(requiredType)) {Object autowiringValue = https://www.isolves.com/it/cxkf/kj/2023-09-12/classObjectEntry.getValue();// 解析自动装配的类型值(主要就是判断当前的值对象是否是ObjectFactory对象)autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);if (requiredType.isInstance(autowiringValue)) {// 要注意这里 , 如果通过registerResolvableDependency添加的对象是个ObjectFactory , 那么最终会调用factory.getObject方法返回真实的对象并且加入到result集合中 。这时候相当于当前类型还是找到了多个Bean还是会报错 。result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);break;}}}for (String candidate : candidateNames) {if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {addCandidateEntry(result, candidate, descriptor, requiredType);}}return result;}}// AutowireUtils.resolveAutowiringValue方法// 该方法中会判断对象是否是ObjectFactorypublic static Object resolveAutowiringValue(Object autowiringValue, Class requiredType) {if (autowiringValue instanceof ObjectFactory && !requiredType.isInstance(autowiringValue)) {ObjectFactory factory = (ObjectFactory


推荐阅读