Spring Basics - XML Autowiring and Bean Scope
In this blog post we’ll approach how autowiring works in the Spring framework. We’ll showcase autowiring via XML configuration. Also, we’ll dive into understanding singleton and prototype bean scopes.
- autowire byName demo
- autowire byType demo
- autowire constructor demo
- singleton scope demo
- prototype scope demo
By default, autowiring isn’t enabled in Spring. With autowiring enabled in Spring, we don’t have to specify all the property values in bean configurations. Autowiring is for non-primitive values and isn't for injecting primitive and string values. The Spring container will auto-initialize (autowire) the dependencies for non-primitive values. Thus, we can omit
constructor-arg attributes in bean definitions.
We’re going to take a look at all the modes of autowiring and how to use them.
|byName||Bean dependency is autowired based on the property name. If the matching bean doesn’t exist in the container then the bean will remain unwired. It internally uses setter injection.|
|byType||Autowires the bean dependency based on the property type. Properties for which there is no matching bean will remain unwired. Spring throws an exception if there’s more than one bean of the same type exists in the container. It internally uses setter injection.|
|constructor||It’s the same as autowiring byType, but through constructor arguments. Spring autowires the dependency based on constructor argument type through constructor injection. Spring throws an exception if there’s more than one bean of the same type exists in the container.|
|no||Default mode which means no autowiring.|
In byName mode, Spring looks for a bean in the IoC container with the
id with the same name as the property name to autowire the dependency. For example, we see in the below code
PostGenerator is a dependency and it has a name of
All we need to do is specify the
autowire attribute of our
BlogPostService bean to
byName. After, we’d make sure our dependency bean has the same
id as the variable given in the
BlogPostService. Also, we need the respective setter methods for Spring to inject the bean using setter injection.
In byType mode, Spring autowires beans in the IoC container with the same type as the property.
In byType mode, we don’t need the bean
id to be the same as property name. We autowired based on the type of the property instead of the name. Like byName, byType requires setter methods in the class for Spring to inject the bean dependency.
In constructor mode, Spring autowires beans like byType mode. But, Spring uses constructor injection instead of setter injection. Hence, it’s required to have a parameterized constructor in the respective class.
In the constructor mode of autowiring, there’s no need to have the bean id the same as the property name as the dependency. We’re now autowiring based on the type of property instead of its name. But we need a parameterized constructor in the
BlogPostService class. This is because the dependency is now injected through the constructor.
When we create beans with configuration metadata what we’re doing is writing a recipe for those beans. This recipe serves as a template for our application when injecting dependencies. Now, this also means that like a class, you can have many object instances created from a single recipe.
When a bean is singleton scoped, there is one shared instance of the managed bean. All requests for beans with matching
ids will have one bean instance returned Spring.
When we run this code, we are able to see that the hashCode of the two
BlogPostService class instances are the same. This is because they’re referring to the same bean instance in the Spring container.
When a bean is protoype scoped, Spring creates a new bean instance every time a request is made for that bean. All requests for beans with matching
ids will be created uniquely by the Spring container.
When we run this code, we see that the hashCode of the two
BlogPostService class instances are different. This is because they refer to different bean instances in the Spring container.
To conclude we’ll compare all the autowiring modes. We learned that autowiring by default is set to no mode. byName autowiring will autowire beans based on name through setter injection. byType autowiring will autowire based on the bean type through setter injection. Autowiring in constructor mode will autowire beans through the parameterized constructor of the respective class by type.
We can configure class dependencies and values from bean definitions. But, also the scope of the objects created from a particular bean definition is important. To compare between singleton and prototype scopes we can compare bean hashCodes to see whether we are getting the same bean or a different bean.