I'm a little confused as to how the inversion of control (IoC
) works in Spring
.
Say I have a service class called UserServiceImpl
that implements UserService
interface.
How would this be @Autowired
?
And in my Controllers
, how would I instantiate
an instance
of this service?
Would I just do the following?
UserService userService = new UserServiceImpl();
First, and most important - all Spring beans are managed - they "live" inside a container, called "application context".
Second, each application has an entry point to that context. Web applications have a Servlet, JSF uses a el-resolver, etc. Also, there is a place where the application context is bootstrapped and all beans - autowired. In web applications this can be a startup listener.
Autowiring happens by placing an instance of one bean into the desired field in an instance of another bean. Both classes should be beans, i.e. they should be defined to live in the application context.
What is "living" in the application context? This means that the context instantiates the objects, not you. I.e. - you never make
new UserServiceImpl()
- the container finds each injection point and sets an instance there.In your controllers, you just have the following:
A few notes:
applicationContext.xml
you should enable the<context:component-scan>
so that classes are scanned for the@Controller
,@Service
, etc. annotations.UserServiceImpl
should also be defined as bean - either using<bean id=".." class="..">
or using the@Service
annotation. Since it will be the only implementor ofUserService
, it will be injected.@Autowired
annotation, Spring can use XML-configurable autowiring. In that case all fields that have a name or type that matches with an existing bean automatically get a bean injected. In fact, that was the initial idea of autowiring - to have fields injected with dependencies without any configuration. Other annotations like@Inject
,@Resource
can also be used.Depends on whether you went the annotations route or the bean XML definition route.
Say you had the beans defined in your
applicationContext.xml
:The autowiring happens when the application starts up. So, in
fooController
, which for arguments sake wants to use theUserServiceImpl
class, you'd annotate it as follows:When it sees
@Autowired
, Spring will look for a class that matches the property in the applicationContext, and inject it automatically. If you have more than 1 UserService bean, then you'll have to qualify which one it should use.If you do the following:
It will not pick up the @Autowired unless you set it yourself.
The whole concept of inversion of control means you are free from a chore to instantiate objects manually and provide all necessary dependencies. When you annotate class with appropriate annotation (e.g.
@Service
) Spring will automatically instantiate object for you. If you are not familiar with annotations you can also use XML file instead. However, it's not a bad idea to instantiate classes manually (with thenew
keyword) in unit tests when you don't want to load the whole spring context.Spring dependency inject help you to remove coupling from your classes. Instead of creating object like this
You will be using this after introducing DI
For achieving this you need to create a bean of your service in your ServiceConfiguration file. After that you need to Import that ServiceConfiguration class to your WebApplicationConfiguration class so that you can Autowire that bean into your Controller like this.
You can find a java configuration based POC here example
@Autowired
is an annotation introduced in Spring 2.5, and it's used only for injection.For example:
How does @Autowired work internally?
Ex -
.xml file it will look alike if not using @Autowired
If you are using @Autowired then
.xml file it will look alike if not using @Autowired
If still have some doubt then go through below live demo
How does @Autowired work internally ?