spring @autowired 按条件注入 null的时候不报异常

举报
隔壁老汪 发表于 2022/06/24 00:12:07 2022/06/24
【摘要】 现象描述 在开发过程中,遇到一种情况,当某种条件下才创建beanA,而这个beanA恰好又被另外一个beanB引用了,当beanA为null的时候beanB初始化失败,代码如下 @Autowired private ProducerBean producer; 抛出异常如下: nested exception is or...

现象描述

在开发过程中,遇到一种情况,当某种条件下才创建beanA,而这个beanA恰好又被另外一个beanB引用了,当beanA为null的时候beanB初始化失败,代码如下


  
  1. @Autowired
  2. private ProducerBean producer;

抛出异常如下:


  
  1. nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'aliMqService':
  2. Unsatisfied dependency expressed through field 'producer'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type
  3. 'com.aliyun.openservices.ons.api.bean.ProducerBean' available: expected at least 1 bean
  4. which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

解决方式比较简单

查看源码@Autowired中有个required属性,设置为false,就不会报错了

原理分析
 

先找到源码路径

Autowired.class对应着AutowiredAnnotationBeanPostProcessor.class

默认required为true


  
  1. public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
  2. implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
  3. protected final Log logger = LogFactory.getLog(getClass());
  4. private final Set<Class<? extends Annotation>> autowiredAnnotationTypes =
  5. new LinkedHashSet<Class<? extends Annotation>>();
  6. private String requiredParameterName = "required";
  7. private boolean requiredParameterValue = true;
  8. private int order = Ordered.LOWEST_PRECEDENCE - 2;
  9. // bean工厂类
  10. private ConfigurableListableBeanFactory beanFactory;
  11. private final Set<String> lookupMethodsChecked =
  12. Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(256));
  13. private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache =
  14. new ConcurrentHashMap<Class<?>, Constructor<?>[]>(256);
  15. private final Map<String, InjectionMetadata> injectionMetadataCache =
  16. new ConcurrentHashMap<String, InjectionMetadata>(256);
  17. // 构造函数
  18. /**
  19. * Create a new AutowiredAnnotationBeanPostProcessor
  20. * for Spring's standard {@link Autowired} annotation.
  21. * <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
  22. */
  23. @SuppressWarnings("unchecked")
  24. public AutowiredAnnotationBeanPostProcessor() {
  25. this.autowiredAnnotationTypes.add(Autowired.class);
  26. this.autowiredAnnotationTypes.add(Value.class);
  27. try {
  28. this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
  29. ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
  30. logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
  31. }
  32. catch (ClassNotFoundException ex) {
  33. // JSR-330 API not available - simply skip.
  34. }
  35. }
  36. // 在constructors, fields,settter方法,属性配置方法 上设置 ‘autowired’
  37. /**
  38. * Set the 'autowired' annotation type, to be used on constructors, fields,
  39. * setter methods and arbitrary config methods.
  40. * <p>The default autowired annotation type is the Spring-provided
  41. * {@link Autowired} annotation, as well as {@link Value}.
  42. * <p>This setter property exists so that developers can provide their own
  43. * (non-Spring-specific) annotation type to indicate that a member is
  44. * supposed to be autowired.
  45. */
  46. public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) {
  47. Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null");
  48. this.autowiredAnnotationTypes.clear();
  49. this.autowiredAnnotationTypes.add(autowiredAnnotationType);
  50. }
  51. /**
  52. * Set the 'autowired' annotation types, to be used on constructors, fields,
  53. * setter methods and arbitrary config methods.
  54. * <p>The default autowired annotation type is the Spring-provided
  55. * {@link Autowired} annotation, as well as {@link Value}.
  56. * <p>This setter property exists so that developers can provide their own
  57. * (non-Spring-specific) annotation types to indicate that a member is
  58. * supposed to be autowired.
  59. */
  60. public void setAutowiredAnnotationTypes(Set<Class<? extends Annotation>> autowiredAnnotationTypes) {
  61. Assert.notEmpty(autowiredAnnotationTypes, "'autowiredAnnotationTypes' must not be empty");
  62. this.autowiredAnnotationTypes.clear();
  63. this.autowiredAnnotationTypes.addAll(autowiredAnnotationTypes);
  64. }
  65. /**
  66. * Set the name of a parameter of the annotation that specifies
  67. * whether it is required.
  68. * @see #setRequiredParameterValue(boolean)
  69. */
  70. public void setRequiredParameterName(String requiredParameterName) {
  71. this.requiredParameterName = requiredParameterName;
  72. }
  73. //设置required 为true 或者false
  74. /**
  75. * Set the boolean value that marks a dependency as required
  76. * <p>For example if using 'required=true' (the default),
  77. * this value should be {@code true}; but if using
  78. * 'optional=false', this value should be {@code false}.
  79. * @see #setRequiredParameterName(String)
  80. */
  81. public void setRequiredParameterValue(boolean requiredParameterValue) {
  82. this.requiredParameterValue = requiredParameterValue;
  83. }
  84. public void setOrder(int order) {
  85. this.order = order;
  86. }
  87. @Override
  88. public int getOrder() {
  89. return this.order;
  90. }
  91. // bean工厂类
  92. @Override
  93. public void setBeanFactory(BeanFactory beanFactory) {
  94. if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
  95. throw new IllegalArgumentException(
  96. "AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
  97. }
  98. this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
  99. }
  100. @Override
  101. public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
  102. if (beanType != null) {
  103. InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
  104. metadata.checkConfigMembers(beanDefinition);
  105. }
  106. }
  107. @Override
  108. public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
  109. throws BeanCreationException {
  110. // Let's check for lookup methods here..
  111. if (!this.lookupMethodsChecked.contains(beanName)) {
  112. try {
  113. ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
  114. @Override
  115. public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
  116. Lookup lookup = method.getAnnotation(Lookup.class);
  117. if (lookup != null) {
  118. LookupOverride override = new LookupOverride(method, lookup.value());
  119. try {
  120. RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
  121. mbd.getMethodOverrides().addOverride(override);
  122. }
  123. catch (NoSuchBeanDefinitionException ex) {
  124. throw new BeanCreationException(beanName,
  125. "Cannot apply @Lookup to beans without corresponding bean definition");
  126. }
  127. }
  128. }
  129. });
  130. }
  131. catch (IllegalStateException ex) {
  132. throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
  133. }
  134. catch (NoClassDefFoundError err) {
  135. throw new BeanCreationException(beanName, "Failed to introspect bean class [" + beanClass.getName() +
  136. "] for lookup method metadata: could not find class that it depends on", err);
  137. }
  138. this.lookupMethodsChecked.add(beanName);
  139. }
  140. // Quick check on the concurrent map first, with minimal locking.
  141. Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
  142. if (candidateConstructors == null) {
  143. // Fully synchronized resolution now...
  144. synchronized (this.candidateConstructorsCache) {
  145. candidateConstructors = this.candidateConstructorsCache.get(beanClass);
  146. if (candidateConstructors == null) {
  147. Constructor<?>[] rawCandidates;
  148. try {
  149. rawCandidates = beanClass.getDeclaredConstructors();
  150. }
  151. catch (Throwable ex) {
  152. throw new BeanCreationException(beanName,
  153. "Resolution of declared constructors on bean Class [" + beanClass.getName() +
  154. "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
  155. }
  156. List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
  157. Constructor<?> requiredConstructor = null;
  158. Constructor<?> defaultConstructor = null;
  159. for (Constructor<?> candidate : rawCandidates) {
  160. AnnotationAttributes ann = findAutowiredAnnotation(candidate);
  161. if (ann == null) {
  162. Class<?> userClass = ClassUtils.getUserClass(beanClass);
  163. if (userClass != beanClass) {
  164. try {
  165. Constructor<?> superCtor =
  166. userClass.getDeclaredConstructor(candidate.getParameterTypes());
  167. ann = findAutowiredAnnotation(superCtor);
  168. }
  169. catch (NoSuchMethodException ex) {
  170. // Simply proceed, no equivalent superclass constructor found...
  171. }
  172. }
  173. }
  174. if (ann != null) {
  175. if (requiredConstructor != null) {
  176. throw new BeanCreationException(beanName,
  177. "Invalid autowire-marked constructor: " + candidate +
  178. ". Found constructor with 'required' Autowired annotation already: " +
  179. requiredConstructor);
  180. }
  181. boolean required = determineRequiredStatus(ann);
  182. if (required) {
  183. if (!candidates.isEmpty()) {
  184. throw new BeanCreationException(beanName,
  185. "Invalid autowire-marked constructors: " + candidates +
  186. ". Found constructor with 'required' Autowired annotation: " +
  187. candidate);
  188. }
  189. requiredConstructor = candidate;
  190. }
  191. candidates.add(candidate);
  192. }
  193. else if (candidate.getParameterTypes().length == 0) {
  194. defaultConstructor = candidate;
  195. }
  196. }
  197. if (!candidates.isEmpty()) {
  198. // Add default constructor to list of optional constructors, as fallback.
  199. if (requiredConstructor == null) {
  200. if (defaultConstructor != null) {
  201. candidates.add(defaultConstructor);
  202. }
  203. else if (candidates.size() == 1 && logger.isWarnEnabled()) {
  204. logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
  205. "': single autowire-marked constructor flagged as optional - " +
  206. "this constructor is effectively required since there is no " +
  207. "default constructor to fall back to: " + candidates.get(0));
  208. }
  209. }
  210. candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
  211. }
  212. else if (rawCandidates.length == 1 && rawCandidates[0].getParameterTypes().length > 0) {
  213. candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
  214. }
  215. else {
  216. candidateConstructors = new Constructor<?>[0];
  217. }
  218. this.candidateConstructorsCache.put(beanClass, candidateConstructors);
  219. }
  220. }
  221. }
  222. return (candidateConstructors.length > 0 ? candidateConstructors : null);
  223. }
  224. @Override
  225. public PropertyValues postProcessPropertyValues(
  226. PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
  227. InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
  228. try {
  229. metadata.inject(bean, beanName, pvs);
  230. }
  231. catch (BeanCreationException ex) {
  232. throw ex;
  233. }
  234. catch (Throwable ex) {
  235. throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
  236. }
  237. return pvs;
  238. }
  239. /**
  240. * 'Native' processing method for direct calls with an arbitrary target instance,
  241. * resolving all of its fields and methods which are annotated with {@code @Autowired}.
  242. * @param bean the target instance to process
  243. * @throws BeanCreationException if autowiring failed
  244. */
  245. public void processInjection(Object bean) throws BeanCreationException {
  246. Class<?> clazz = bean.getClass();
  247. InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
  248. try {
  249. metadata.inject(bean, null, null);
  250. }
  251. catch (BeanCreationException ex) {
  252. throw ex;
  253. }
  254. catch (Throwable ex) {
  255. throw new BeanCreationException(
  256. "Injection of autowired dependencies failed for class [" + clazz + "]", ex);
  257. }
  258. }
  259. private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
  260. // Fall back to class name as cache key, for backwards compatibility with custom callers.
  261. String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
  262. // Quick check on the concurrent map first, with minimal locking.
  263. InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
  264. if (InjectionMetadata.needsRefresh(metadata, clazz)) {
  265. synchronized (this.injectionMetadataCache) {
  266. metadata = this.injectionMetadataCache.get(cacheKey);
  267. if (InjectionMetadata.needsRefresh(metadata, clazz)) {
  268. if (metadata != null) {
  269. metadata.clear(pvs);
  270. }
  271. try {
  272. metadata = buildAutowiringMetadata(clazz);
  273. this.injectionMetadataCache.put(cacheKey, metadata);
  274. }
  275. catch (NoClassDefFoundError err) {
  276. throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
  277. "] for autowiring metadata: could not find class that it depends on", err);
  278. }
  279. }
  280. }
  281. }
  282. return metadata;
  283. }
  284. private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
  285. LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
  286. Class<?> targetClass = clazz;
  287. do {
  288. final LinkedList<InjectionMetadata.InjectedElement> currElements =
  289. new LinkedList<InjectionMetadata.InjectedElement>();
  290. ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
  291. @Override
  292. public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
  293. AnnotationAttributes ann = findAutowiredAnnotation(field);
  294. if (ann != null) {
  295. if (Modifier.isStatic(field.getModifiers())) {
  296. if (logger.isWarnEnabled()) {
  297. logger.warn("Autowired annotation is not supported on static fields: " + field);
  298. }
  299. return;
  300. }
  301. boolean required = determineRequiredStatus(ann);
  302. currElements.add(new AutowiredFieldElement(field, required));
  303. }
  304. }
  305. });
  306. ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
  307. @Override
  308. public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
  309. Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
  310. if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
  311. return;
  312. }
  313. AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
  314. if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
  315. if (Modifier.isStatic(method.getModifiers())) {
  316. if (logger.isWarnEnabled()) {
  317. logger.warn("Autowired annotation is not supported on static methods: " + method);
  318. }
  319. return;
  320. }
  321. if (method.getParameterTypes().length == 0) {
  322. if (logger.isWarnEnabled()) {
  323. logger.warn("Autowired annotation should only be used on methods with parameters: " +
  324. method);
  325. }
  326. }
  327. boolean required = determineRequiredStatus(ann);
  328. PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
  329. currElements.add(new AutowiredMethodElement(method, required, pd));
  330. }
  331. }
  332. });
  333. elements.addAll(0, currElements);
  334. targetClass = targetClass.getSuperclass();
  335. }
  336. while (targetClass != null && targetClass != Object.class);
  337. return new InjectionMetadata(clazz, elements);
  338. }
  339. private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
  340. if (ao.getAnnotations().length > 0) {
  341. for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
  342. AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
  343. if (attributes != null) {
  344. return attributes;
  345. }
  346. }
  347. }
  348. return null;
  349. }
  350. /**
  351. * Determine if the annotated field or method requires its dependency.
  352. * <p>A 'required' dependency means that autowiring should fail when no beans
  353. * are found. Otherwise, the autowiring process will simply bypass the field
  354. * or method when no beans are found.
  355. * @param ann the Autowired annotation
  356. * @return whether the annotation indicates that a dependency is required
  357. */
  358. protected boolean determineRequiredStatus(AnnotationAttributes ann) {
  359. return (!ann.containsKey(this.requiredParameterName) ||
  360. this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
  361. }
  362. /**
  363. * Obtain all beans of the given type as autowire candidates.
  364. * @param type the type of the bean
  365. * @return the target beans, or an empty Collection if no bean of this type is found
  366. * @throws BeansException if bean retrieval failed
  367. */
  368. protected <T> Map<String, T> findAutowireCandidates(Class<T> type) throws BeansException {
  369. if (this.beanFactory == null) {
  370. throw new IllegalStateException("No BeanFactory configured - " +
  371. "override the getBeanOfType method or specify the 'beanFactory' property");
  372. }
  373. return BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type);
  374. }
  375. /**
  376. * Register the specified bean as dependent on the autowired beans.
  377. */
  378. private void registerDependentBeans(String beanName, Set<String> autowiredBeanNames) {
  379. if (beanName != null) {
  380. for (String autowiredBeanName : autowiredBeanNames) {
  381. if (this.beanFactory.containsBean(autowiredBeanName)) {
  382. this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
  383. }
  384. if (logger.isDebugEnabled()) {
  385. logger.debug("Autowiring by type from bean name '" + beanName +
  386. "' to bean named '" + autowiredBeanName + "'");
  387. }
  388. }
  389. }
  390. }
  391. /**
  392. * Resolve the specified cached method argument or field value.
  393. */
  394. private Object resolvedCachedArgument(String beanName, Object cachedArgument) {
  395. if (cachedArgument instanceof DependencyDescriptor) {
  396. DependencyDescriptor descriptor = (DependencyDescriptor) cachedArgument;
  397. return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
  398. }
  399. else {
  400. return cachedArgument;
  401. }
  402. }
  403. /**
  404. * Class representing injection information about an annotated field.
  405. */
  406. private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
  407. private final boolean required;
  408. private volatile boolean cached = false;
  409. private volatile Object cachedFieldValue;
  410. public AutowiredFieldElement(Field field, boolean required) {
  411. super(field, null);
  412. this.required = required;
  413. }
  414. @Override
  415. protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
  416. Field field = (Field) this.member;
  417. Object value;
  418. if (this.cached) {
  419. value = resolvedCachedArgument(beanName, this.cachedFieldValue);
  420. }
  421. else {
  422. DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
  423. desc.setContainingClass(bean.getClass());
  424. Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
  425. TypeConverter typeConverter = beanFactory.getTypeConverter();
  426. try {
  427. value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
  428. }
  429. catch (BeansException ex) {
  430. throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
  431. }
  432. synchronized (this) {
  433. if (!this.cached) {
  434. if (value != null || this.required) {
  435. this.cachedFieldValue = desc;
  436. registerDependentBeans(beanName, autowiredBeanNames);
  437. if (autowiredBeanNames.size() == 1) {
  438. String autowiredBeanName = autowiredBeanNames.iterator().next();
  439. if (beanFactory.containsBean(autowiredBeanName)) {
  440. if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
  441. this.cachedFieldValue = new ShortcutDependencyDescriptor(
  442. desc, autowiredBeanName, field.getType());
  443. }
  444. }
  445. }
  446. }
  447. else {
  448. this.cachedFieldValue = null;
  449. }
  450. this.cached = true;
  451. }
  452. }
  453. }
  454. if (value != null) {
  455. ReflectionUtils.makeAccessible(field);
  456. field.set(bean, value);
  457. }
  458. }
  459. }
  460. /**
  461. * Class representing injection information about an annotated method.
  462. */
  463. private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {
  464. private final boolean required;
  465. private volatile boolean cached = false;
  466. private volatile Object[] cachedMethodArguments;
  467. public AutowiredMethodElement(Method method, boolean required, PropertyDescriptor pd) {
  468. super(method, pd);
  469. this.required = required;
  470. }
  471. @Override
  472. protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
  473. if (checkPropertySkipping(pvs)) {
  474. return;
  475. }
  476. Method method = (Method) this.member;
  477. Object[] arguments;
  478. if (this.cached) {
  479. // Shortcut for avoiding synchronization...
  480. arguments = resolveCachedArguments(beanName);
  481. }
  482. else {
  483. Class<?>[] paramTypes = method.getParameterTypes();
  484. arguments = new Object[paramTypes.length];
  485. DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
  486. Set<String> autowiredBeans = new LinkedHashSet<String>(paramTypes.length);
  487. TypeConverter typeConverter = beanFactory.getTypeConverter();
  488. for (int i = 0; i < arguments.length; i++) {
  489. MethodParameter methodParam = new MethodParameter(method, i);
  490. DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
  491. currDesc.setContainingClass(bean.getClass());
  492. descriptors[i] = currDesc;
  493. try {
  494. Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
  495. if (arg == null && !this.required) {
  496. arguments = null;
  497. break;
  498. }
  499. arguments[i] = arg;
  500. }
  501. catch (BeansException ex) {
  502. throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
  503. }
  504. }
  505. synchronized (this) {
  506. if (!this.cached) {
  507. if (arguments != null) {
  508. this.cachedMethodArguments = new Object[paramTypes.length];
  509. for (int i = 0; i < arguments.length; i++) {
  510. this.cachedMethodArguments[i] = descriptors[i];
  511. }
  512. registerDependentBeans(beanName, autowiredBeans);
  513. if (autowiredBeans.size() == paramTypes.length) {
  514. Iterator<String> it = autowiredBeans.iterator();
  515. for (int i = 0; i < paramTypes.length; i++) {
  516. String autowiredBeanName = it.next();
  517. if (beanFactory.containsBean(autowiredBeanName)) {
  518. if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
  519. this.cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
  520. descriptors[i], autowiredBeanName, paramTypes[i]);
  521. }
  522. }
  523. }
  524. }
  525. }
  526. else {
  527. this.cachedMethodArguments = null;
  528. }
  529. this.cached = true;
  530. }
  531. }
  532. }
  533. if (arguments != null) {
  534. try {
  535. ReflectionUtils.makeAccessible(method);
  536. method.invoke(bean, arguments);
  537. }
  538. catch (InvocationTargetException ex){
  539. throw ex.getTargetException();
  540. }
  541. }
  542. }
  543. private Object[] resolveCachedArguments(String beanName) {
  544. if (this.cachedMethodArguments == null) {
  545. return null;
  546. }
  547. Object[] arguments = new Object[this.cachedMethodArguments.length];
  548. for (int i = 0; i < arguments.length; i++) {
  549. arguments[i] = resolvedCachedArgument(beanName, this.cachedMethodArguments[i]);
  550. }
  551. return arguments;
  552. }
  553. }
  554. /**
  555. * DependencyDescriptor variant with a pre-resolved target bean name.
  556. */
  557. @SuppressWarnings("serial")
  558. private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
  559. private final String shortcut;
  560. private final Class<?> requiredType;
  561. public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class<?> requiredType) {
  562. super(original);
  563. this.shortcut = shortcut;
  564. this.requiredType = requiredType;
  565. }
  566. @Override
  567. public Object resolveShortcut(BeanFactory beanFactory) {
  568. return resolveCandidate(this.shortcut, this.requiredType, beanFactory);
  569. }
  570. }
  571. }

 

文章来源: blog.csdn.net,作者:隔壁老瓦,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/wxb880114/article/details/83898206

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。