Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to inject collection types correctly by Spring

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces how to correctly inject Spring into the collection type, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let the editor take you to understand it.

Automatic injection of collection types is another powerful feature provided by Spring. When we are convenient to use the feature of dependency injection, we have to think about where the object is injected, how it is created, and why it is injected. Although the purpose of writing the framework is to allow developers to focus on the development of business logic without paying too much attention to the underlying details, but as developers can not really be brainless to use the framework.

Now there is a need: there are multiple user Bean, find out and store it in a List.

1 injection mode 1.1 collection mode

Multiple user Bean definitions:

With automatic injection of collection types, fragmented user Bean can be collected:

This completes the collection type injection:

However, when you continue to add some user, you may not like to use the above injection collection type, but like this:

1.2 Direct assembly mode

Play separately, we should not have any problems, if the two ways coexist, what will happen?

After running the program, it is found that the direct assembly mode does not take effect:

Why is that?

2 Source code parsing

You need to be proficient in how these two injection styles are implemented in Spring.

2.1 Collection Assembly

DefaultListableBeanFactory#resolveMultipleBeans

Private Object resolveMultipleBeans (DependencyDescriptor descriptor, @ Nullable String beanName, @ Nullable Set autowiredBeanNames, @ Nullable TypeConverter typeConverter) {final Class type = descriptor.getDependencyType (); if (descriptor instanceof StreamDependencyDescriptor) {/ / Assembly stream return stream;} else if (type.isArray ()) {/ / Assembly array return result } else if (Collection.class.isAssignableFrom (type) & & type.isInterface ()) {/ / assemble the collection / / get the element type of the collection Class elementType = descriptor.getResolvableType (). AsCollection (). ResolveGeneric (); if (elementType = = null) {return null } / / find all bean Map matchingBeans = findAutowireCandidates (beanName, elementType, new MultiElementDescriptor (descriptor)) based on element type; if (matchingBeans.isEmpty ()) {return null;} if (autowiredBeanNames! = null) {autowiredBeanNames.addAll (matchingBeans.keySet ()) } / / put all bean found in the conversion into the collection and return TypeConverter converter = (typeConverter! = null? TypeConverter: getTypeConverter (); Object result = converter.convertIfNecessary (matchingBeans.values (), type); / /. Return result;} else if (Map.class = = type) {/ / parse map return matchingBeans;} else {return null;}} 1 to get the elementType of the collection type

The target type is defined as List users, so the element type is User:

2 find all Bean based on element type

With elementType, you can find all the Bean based on it:

3 convert all matching Bean according to target type

All the Bean obtained in the previous step is stored in java.util.LinkedHashMap.LinkedValues, which is very different from the target type, so it is converted on demand.

In this case, it needs to be converted to List:

2.2 Direct assembly mode

DefaultListableBeanFactory#findAutowireCandidates

I won't repeat it.

Finally, according to the target type, we directly find the List assembly whose Bean name is users and give it to the userController#users attribute.

What will Spring do when both assembly modes are satisfied?

DefaultListableBeanFactory#doResolveDependency

It is obvious that these two ways of assembly can not exist together, combined with this case:

If any corresponding Bean can be found when using the collection assembly, return

If none of them are found, direct assembly is used.

So the user Bean that is added directly by List in the later stage does not take effect!

3 Correction

Be sure to avoid the coexistence of two ways to assemble assemblies! You can choose only one way.

For example, only direct assembly is used:

Use only the collection method:

How to give user 2 priority output?

Control the spring bean load order:

Use @ Order annotations on Bean, such as @ Order (2). The lower the number, the higher the priority. The default priority is the lowest.

DependsOn uses it so that dependent Bean will be initialized first if it is not initialized.

Add @ Order (number) annotation, the smaller the number, the higher the priority.

When you user these Bean, you will raise the user of id=2 before id=1.

Thank you for reading this article carefully. I hope the article "how to correctly inject Spring into set types" shared by the editor will be helpful to everyone. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report