Inversion of Control (IoC) is the principle that the Spring IoC container, not our classes, creates the objects an app needs, and Dependency Injection (DI) is the pattern Spring uses to pass those objects into the classes that need them.
In Java, we use the new keyword to create instances of dependent classes. For example, ReminderService calls new EmailNotifier() to initialize the EmailNotifier instance, which contains the methods for sending emails. In Spring Framework, we don’t create these objects ourselves. Spring creates the dependent objects and injects them into the classes that need them.
We use IoC and DI to keep creation code out of our business classes. A reminder app can then switch from email to SMS in one place, and a unit test can give ReminderService a fake Notifier.
- Inversion of Control (IoC) is the name of the principle, because the control over creating objects moves from our classes to the Spring IoC container.
- Dependency Injection (DI) is the way the container passes those objects in, most often as constructor arguments, so ReminderService gets its Notifier when Spring creates it.
The following example shows ReminderService without IoC and with IoC and DI, with the result of the call as a comment.
// Without IoC: the class creates its own dependency
public class ReminderService {
private final Notifier notifier = new EmailNotifier(); // always an EmailNotifier
}
// With IoC and DI: Spring creates the Notifier and passes it in
@Service
public class ReminderService {
private final Notifier notifier;
public ReminderService(Notifier notifier) { // constructor injection
this.notifier = notifier;
}
}
String sent = reminderService.remind("Lokesh", "Pay rent"); // "EMAIL to Lokesh: Pay rent"
Notice that the second ReminderService never mentions EmailNotifier, so Spring can pass in any Notifier bean. In other words, IoC is the principle and DI is the pattern that Spring uses to apply it. IoC answers the question “who creates the objects?”, whereas DI answers the question “how does an object get the objects it needs?”.
| Inversion of Control (IoC) | Dependency Injection (DI) | |
|---|---|---|
| What it is | A design principle in which the framework, not our code, controls object creation | A design pattern that applies IoC by passing the dependencies in from outside |
| Question it answers | Who creates and manages the objects? | How does an object receive its dependencies? |
| In Spring | The IoC container, i.e. BeanFactory and ApplicationContext | Constructor, setter and field injection with @Autowired and @Qualifier |
| Example | context.getBean(ReminderService.class) returns a fully wired bean | The container calls public ReminderService(Notifier notifier) with a Notifier bean |
Next, we compare BeanFactory with ApplicationContext and look at the three injection styles. After that, we see how @Primary and @Qualifier choose between two matching Notifier beans, and run the same beans in Spring Core and in Spring Boot.
1. What Is Inversion of Control?
In plain Java, a class creates its collaborators (that is, the other objects it works with) with new and then calls their methods. With inversion of control, the class leaves the object creation to an outside component, called the container or assembler, which creates the objects and connects them at runtime. For example, ReminderService only declares what it needs, most often as an interface type such as Notifier, and never mentions EmailNotifier in its code.
A dependency is an object that another object needs to do its work, so Notifier is a dependency of ReminderService, because the service cannot send a reminder without it. Inversion of control is often summed up as “Don’t call us, we’ll call you”, which is also known as the Hollywood principle. The framework creates our objects and calls our code, whereas our code never asks the framework for the objects it needs.
“The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface.” Martin Fowler, Inversion of Control Containers and the Dependency Injection pattern.
When we move object creation out of our classes, we get four practical benefits.
- The business logic in ReminderService stays separate from the code that creates EmailNotifier or SmsNotifier.
- Each class does one job and knows its collaborators only through their interfaces, such as Notifier.
- We can switch from EmailNotifier to SmsNotifier by moving @Primary to the other class, without changing a line in the classes that use Notifier.
- A unit test can pass a fake Notifier to the constructor and run without starting Spring, as section 6.2 shows.
1.1. Dependency Injection vs Dependency Lookup
IoC comes in two main forms, and they differ in who moves the objects between the container and our class.
- With dependency injection, the container pushes the dependencies into our class through a constructor, a setter or a field.
- With dependency lookup, our class pulls its dependencies from a registry (a central object that returns objects on request). The service locator pattern is the best-known example, and factories and JNDI lookups follow the same idea.

Spring supports both forms. With lookup, our code calls context.getBean(), whereas with injection, the container calls the ReminderService constructor and passes the Notifier bean in.
// Dependency lookup: our code asks the container
ReminderService reminders = context.getBean(ReminderService.class);
// Dependency injection: the container passes the Notifier in
public ReminderService(Notifier notifier) { ... }
In application classes, we prefer injection over lookup. A class that calls getBean() depends on the Spring container, whereas a class with a Notifier constructor parameter depends only on the Notifier interface. So we keep lookup in the code that starts the program, such as the main() method that starts the container, and use injection everywhere else.
2. The Spring IoC Container
In Spring, a bean is an object that the Spring IoC container creates and manages. The container first reads the configuration metadata (the description of which beans to create and how to wire them), which can be annotations such as @Component, @Service and @Bean, or XML files. After that, it creates the beans with their dependencies and manages the lifecycle of each bean until the app shuts down.

The container code is in the packages org.springframework.beans and org.springframework.context. Two interfaces represent the container, namely BeanFactory, which provides the basic configuration and bean management, and ApplicationContext, a sub-interface of BeanFactory that adds the features applications need.
By default, every bean is a singleton within its container, which means the container creates one shared instance, so getBean(ReminderService.class) returns the same object on every call. When we need a new instance every time the bean is requested, we declare the bean with the prototype scope, one of several bean scopes. A singleton managed by the container is simpler than the hand-written Singleton design pattern, because ReminderService stays an ordinary class with a public constructor.
2.1. BeanFactory vs ApplicationContext
BeanFactory is the basic container interface. It holds the bean definitions (the recipe for each bean, such as its class and scope) and creates a bean when we ask for it with getBean(). ApplicationContext extends BeanFactory and adds the features that applications need, such as annotation processing and events. For everyday code, the biggest difference is that a bare BeanFactory ignores @Autowired.
| Feature | BeanFactory (DefaultListableBeanFactory) | ApplicationContext |
|---|---|---|
| Singleton creation | Lazy, on the first getBean() call | Eager, at startup during refresh() |
| @Autowired, @Value, @PostConstruct | Ignored unless we register the post-processors (the classes that process these annotations) ourselves | Processed |
| Events, translated messages (i18n), resource loading | No | Yes |
| @Configuration and component scanning | No | Yes, with AnnotationConfigApplicationContext |
| Typical use | Inside frameworks and in very small embedded setups | Every application, including Spring Boot applications |
The class BeanFactoryVsContextDemo registers EmailNotifier and FieldReminderService in both containers. With a bare DefaultListableBeanFactory, the output shows two problems, namely that the factory creates EmailNotifier only at the first getBean() call, and that the @Autowired field in FieldReminderService stays null, so remind() throws NullPointerException.
var factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("emailNotifier", new RootBeanDefinition(EmailNotifier.class));
factory.registerBeanDefinition("fieldReminderService",
new RootBeanDefinition(FieldReminderService.class));
EmailNotifier notifier = factory.getBean(EmailNotifier.class); // created now, not before
String failed = factory.getBean(FieldReminderService.class)
.remind("Lokesh", "Pay rent"); // NullPointerException
var context = new AnnotationConfigApplicationContext();
context.register(EmailNotifier.class, FieldReminderService.class);
context.refresh(); // creates both beans now
String sent = context.getBean(FieldReminderService.class)
.remind("Lokesh", "Pay rent"); // "EMAIL to Lokesh: Pay rent"
--- BeanFactory ---
Definitions registered
EmailNotifier created
Got EmailNotifier
Got FieldReminderService
NullPointerException: @Autowired field was not injected
--- ApplicationContext ---
Classes registered
EmailNotifier created
Context refreshed
EMAIL to Lokesh: Pay rent
We use an ApplicationContext in every application. A plain BeanFactory skips annotation processing, events and the other context features, so our @Autowired fields stay empty. Older tutorials use XmlBeanFactory, which Spring 3.1 deprecated and which no longer exists in Spring 6 and 7. Spring has several ApplicationContext implementations, such as AnnotationConfigApplicationContext.
3. Dependency Injection Types in Spring
Spring can inject a dependency through a constructor, a setter method or a field. Constructor-based and setter-based dependency injection are the two major variants, and field injection is a third style that relies on @Autowired. Our example classes ReminderService, SetterReminderService and FieldReminderService get the same Notifier bean and differ only in when and how the container passes it in.
3.1. Constructor Injection
With constructor-based dependency injection, the dependencies are constructor parameters. The container finds a matching bean for each parameter and calls the constructor with those beans, so ReminderService is fully initialized from the moment it exists, and its notifier field can be final.
@Service
public class ReminderService {
private final Notifier notifier; // final: set once, never null
public ReminderService(Notifier notifier) { // no @Autowired needed
this.notifier = notifier;
}
}
A class with a single constructor needs no @Autowired annotation. Since Spring 4.3, the container uses that one constructor without the annotation. When a class has several constructors, we put @Autowired on the constructor that Spring must use.
3.2. Setter Injection
With setter-based dependency injection, the container first calls the no-argument constructor and then calls each setter method annotated with @Autowired. Between these two calls, the notifier field of SetterReminderService is still null, which is why the field cannot be final.
@Service
public class SetterReminderService {
private Notifier notifier; // not final, null until the setter runs
@Autowired
public void setNotifier(Notifier notifier) {
this.notifier = notifier;
}
}
Setter injection fits optional dependencies that have a reasonable default value, and dependencies that we want to replace after the bean is created. For example, a reminder service can log through a default logger and switch to an audit logger only in the deployments that define one. For an optional dependency, we write @Autowired(required = false), so the container skips the setter when no matching bean exists, and the field keeps its default value.
3.3. Field Injection
With field injection, the container sets a private field through reflection (the Java API that reads and writes fields at runtime, including private ones). It needs the least code of the three styles, because FieldReminderService has neither a constructor nor a setter for the Notifier.
@Service
public class FieldReminderService {
@Autowired
private Notifier notifier; // set by reflection, cannot be final
}
Outside a Spring container, nothing sets the field. When a unit test calls new FieldReminderService(), the first remind() call throws NullPointerException, and ReminderServiceTest checks this case. To fill the field, the test has to start a Spring context or set the field with reflection.
3.4. Why Constructor Injection Is Recommended
The Spring team recommends constructor injection for required dependencies. Constructor injection keeps required dependencies non-null and returns each bean fully initialized, whereas setter injection is meant for optional dependencies. The three styles differ most in unit tests and in how many dependencies we see at a glance.
| Constructor | Setter | Field | |
|---|---|---|---|
| Field can be final | Yes | No | No |
| Object complete after new | Yes | Only after setNotifier() runs | No |
| Unit test without Spring | new ReminderService(fake) | new, then setNotifier(fake) | Needs a Spring context or reflection |
| Missing bean detected | At startup | At startup (when the setter is required) | At startup |
| Number of dependencies visible at a glance | Yes, every dependency is a constructor parameter | Partly, one setter per dependency | No, hidden among the fields |
| Good for | Required dependencies | Optional or replaceable dependencies | Test classes and quick demos |
A constructor with seven or eight parameters is a warning sign, because a class with that many dependencies often does too many jobs and should be split. Field injection hides the same problem behind short field declarations, so the class can keep growing unnoticed, which is one more reason to prefer constructors.
4. Choosing Between Two Beans With @Primary and @Qualifier
By default, the container autowires by type, so a Notifier parameter receives the one bean that implements Notifier. When two beans implement Notifier, the container cannot decide which one ReminderService should get, and it throws UnsatisfiedDependencyException at startup. A reminder app that sends normal reminders by email and server alerts by SMS has two Notifier beans, so it hits this error as soon as the second notifier is added. ApplicationContextTest shows this case by registering two Notifier beans, named email and sms, without any hint.
UnsatisfiedDependencyException: Error creating bean with name 'reminderService':
Unsatisfied dependency expressed through constructor parameter 0:
No qualifying bean of type 'com.howtodoinjava.core.iocdi.reminder.Notifier' available:
expected single matching bean but found 2: email,sms
Spring offers three ways to resolve the two-bean conflict, and each one works on an injection point (a constructor parameter, setter parameter or field that receives a bean).
- @Primary on one bean makes that bean the default, so every injection point of type Notifier receives it unless the injection point asks for another bean.
- @Qualifier(“beanName”) on an injection point requests one specific bean by its name. By default, a @Component class gets its simple class name with a lowercase first letter as its bean name, so SmsNotifier becomes smsNotifier.
- Without either annotation, Spring falls back to the parameter or field name and compares it with the bean names, so a parameter named sms receives the sms bean.
@Component
@Primary
public class EmailNotifier implements Notifier { ... }
@Component
public class SmsNotifier implements Notifier { ... }
@Service
public class UrgentReminderService {
public UrgentReminderService(@Qualifier("smsNotifier") Notifier notifier) { ... }
}
String normal = reminderService.remind("Lokesh", "Pay rent"); // "EMAIL to Lokesh: Pay rent"
String urgent = urgentReminderService.remind("Lokesh", "Server down"); // "SMS to Lokesh: Server down"
When both are present, @Qualifier wins over @Primary. So we put @Primary on the bean that most classes need, such as EmailNotifier, and add @Qualifier only where a class needs the other bean, as UrgentReminderService does. The parameter-name fallback also works, but renaming the parameter can change which bean Spring injects without any error, so an explicit @Qualifier is safer.
5. IoC and DI Example With AnnotationConfigApplicationContext
The following example is a small reminder application on Java 25 and Spring Framework 7.0.9. Two Notifier beans, EmailNotifier and SmsNotifier, send reminders by email or by SMS, and four services use them with the three injection styles from section 3. The complete project on GitHub builds and runs with Maven.
5.1. Maven Dependency
A Spring Core application needs only the spring-context dependency, which brings spring-beans and spring-core in as transitive dependencies.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>7.0.9</version>
</dependency>
5.2. Configuration and Main Class
A @Configuration class holds our Spring configuration. Its @ComponentScan(basePackageClasses = ReminderService.class) annotation tells the container to scan the package of ReminderService for @Component and @Service classes and to register each of them as a bean.
@Configuration
@ComponentScan(basePackageClasses = ReminderService.class)
public class AppConfig {
}
AnnotationConfigApplicationContext is the ApplicationContext implementation for Java-based configuration. Its constructor scans the package, creates the singleton beans and injects their dependencies before it returns. The try-with-resources block closes the context at the end, and closing the context destroys the beans.
System.out.println("1. Starting the container");
try (var context = new AnnotationConfigApplicationContext(AppConfig.class)) {
System.out.println("2. Using the beans");
ReminderService reminders = context.getBean(ReminderService.class);
UrgentReminderService urgent = context.getBean(UrgentReminderService.class);
SetterReminderService setter = context.getBean(SetterReminderService.class);
FieldReminderService field = context.getBean(FieldReminderService.class);
System.out.println(reminders.remind("Lokesh", "Pay rent"));
System.out.println(urgent.remind("Lokesh", "Server down"));
System.out.println(setter.remind("Lokesh", "Water plants"));
System.out.println(field.remind("Lokesh", "Call mom"));
}
5.3. Output
The EmailNotifier and SmsNotifier constructors each print one line. Both lines appear before “2. Using the beans”, because the ApplicationContext creates all singleton beans eagerly at startup and not on the first getBean() call.
mvn -q compile exec:java -Dexec.mainClass=com.howtodoinjava.core.iocdi.plain.IocDiDemo
1. Starting the container
EmailNotifier created
SmsNotifier created
2. Using the beans
EMAIL to Lokesh: Pay rent
SMS to Lokesh: Server down
EMAIL to Lokesh: Water plants
EMAIL to Lokesh: Call mom
The container creates each notifier only once, so all four services share the same two notifier instances. ReminderService, SetterReminderService and FieldReminderService received the @Primary bean EmailNotifier, whereas UrgentReminderService received SmsNotifier through @Qualifier(“smsNotifier”).
6. IoC and DI Example With Spring Boot
Spring Boot uses the same IoC container, because SpringApplication.run() creates an ApplicationContext. The @SpringBootApplication annotation turns on component scanning and auto-configuration, which means that Spring Boot creates common beans for us based on the libraries on the classpath. So the reminder package with its notifiers and services works in Spring Boot without any change.
6.1. Spring Boot Application
The Spring Boot application needs the spring-boot-starter dependency, which already includes spring-context. A CommandLineRunner bean runs its code once the application has started, and the container injects ReminderService and UrgentReminderService into the parameters of its @Bean method run().
@SpringBootApplication(scanBasePackageClasses = ReminderService.class)
public class ReminderApplication {
public static void main(String[] args) {
SpringApplication.run(ReminderApplication.class, args);
}
@Bean
CommandLineRunner run(ReminderService reminders, UrgentReminderService urgent) {
return args -> {
System.out.println(reminders.remind("Lokesh", "Pay rent"));
System.out.println(urgent.remind("Lokesh", "Server down"));
};
}
}
The scanBasePackageClasses attribute points the component scan at the reminder package, which we need here because ReminderApplication is in the sibling boot package. In a typical project, the application class sits in the root package, so the default scan finds every bean and the attribute is not needed.
:: Spring Boot :: (v4.1.1)
INFO --- [main] c.h.core.iocdi.boot.ReminderApplication : Starting ReminderApplication using Java 25.0.4.1
EmailNotifier created
SmsNotifier created
INFO --- [main] c.h.core.iocdi.boot.ReminderApplication : Started ReminderApplication in 0.744 seconds
EMAIL to Lokesh: Pay rent
SMS to Lokesh: Server down
6.2. Testing Classes That Use Constructor Injection
We can see that constructor injection pays off in unit tests. ReminderServiceTest creates the service with new and passes a lambda as the Notifier, so no Spring container starts and the test checks only the logic of ReminderService.
var service = new ReminderService((to, text) -> "TEST to " + to + ": " + text);
String sent = service.remind("Lokesh", "Pay rent"); // "TEST to Lokesh: Pay rent"
A @SpringBootTest starts the full application context and checks the wiring itself, for example that @Primary and @Qualifier select the right notifier for each service. The project has 8 tests, and mvn test passes all of them.
7. IoC vs DI FAQs
7.1. Is IoC the Same as Dependency Injection?
No. IoC is the general principle that a framework controls object creation and the program flow, whereas DI is one specific way to implement it. Dependency lookup with getBean(), template methods and event callbacks are also forms of IoC, but none of them is DI. In everyday Spring talk, people use “IoC container” and “DI container” for the same thing, because the Spring container does both jobs.
7.2. Is @Autowired Required on a Constructor?
No, not for a class with a single constructor, because Spring uses that constructor without it. When a class has two or more constructors, one of them needs @Autowired, or else Spring falls back to the no-argument constructor and throws BeanCreationException at startup when no such constructor exists. Setter and field injection always need @Autowired, or @Inject from Jakarta Inject.
7.3. How Is DI Different From the Service Locator Pattern?
Every class that uses a service locator depends on the locator, whereas a class that uses DI depends only on the interfaces it needs. A service locator is one object that knows how to find every service the application needs, and classes ask it for their dependencies, for example with locator.get(Notifier.class). The locator hides the concrete implementations, but each class still has to know the locator and its methods. With DI, ReminderService receives its Notifier and never asks for anything, so a unit test passes a fake Notifier and needs no locator setup.
7.4. What Is Interface Injection, Such as ApplicationContextAware?
Interface injection means that a class implements a special interface, and the container calls a method of that interface to pass in the dependency. In Spring, the Aware interfaces work this way, so a bean that implements ApplicationContextAware receives the container through setApplicationContext(). These interfaces tie a class to the Spring API, so we use them only in infrastructure code. In application code, a constructor parameter of type ApplicationContext gives the same access without the extra interface.
8. Conclusion
IoC is the principle that the container, not our code, creates the objects and connects them, and DI is the way the Spring container connects them, through constructors, setters or fields. We use an ApplicationContext as the container, because a bare BeanFactory creates singletons lazily and ignores annotations such as @Autowired. Constructor injection is the recommended style, because the fields can be final and the bean is complete after creation, so a unit test can call the constructor without Spring.
When several beans share a type, @Primary sets the default bean, whereas @Qualifier selects a specific bean at one injection point. The same beans run unchanged in Spring Core with AnnotationConfigApplicationContext and in Spring Boot with SpringApplication.run(). Beans and wiring go further with autowiring by type and by name, and with the rest of the Spring tutorials.
9. References
- Spring Framework Reference: Introduction to the Spring IoC Container and Beans
- Spring Framework Reference: Dependency Injection
- Spring Framework Reference: The BeanFactory API
- Spring Framework Reference: Using @Autowired
- Spring Framework Reference: Fine-tuning Autowiring with @Primary
- Spring Framework Reference: Fine-tuning Autowiring with Qualifiers
- Spring Framework Reference: Instantiating the Spring Container with AnnotationConfigApplicationContext
- Spring Boot Reference: Spring Beans and Dependency Injection
- Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern
Happy Learning !!
Thanks a lot Lokesh sir. U explained very well as always. Thanks for being mentor for so many tech ppl like me.
Your Welcome !!
You are Welcome !!
Hi pankaj,
I think the question you asked should be — is ioc possible WITHOUT di ?
It may be a typo.
And thanks for the discussion on this. It helped to clearly understand ioc and di
Hi Lokesh,
your blog really gives me a good insight of the technology.
Thanks for taking time and pain in collecting this information and making it available for the java geeks.
Great work and keep going.
All The Best
Hi lokesh,
I got this interview question in one of the interviews.
Is IOC possible with DI?
I answered Yes.
DI is Injecting Dependancies.
Since the process of DI is managed by the container and not us , the flow is reversed hence it is Inversion Of Control.
So ideally, The Servlet which instantiated by container, whose lifecyle methods are managed by the web container, is also IOC? but not DI?
Am I correct? Please explain.
Regards,
-Pankaj.
You are right for most of the part. I have only different opinion on example given i.e. Servlets.
IOC basically facilitates having different components designed and coded separately and later used together by defining their relation with DI. In case of servlets we do not have multiple components. There is only one component i.e. servlet and you can not change the way how a servlet works. A servlet is basically combination of front controller and mediator pattern, which container uses internally.
https://en.wikipedia.org/wiki/Front_Controller_pattern
https://en.wikipedia.org/wiki/Mediator_pattern
Actually, it is a very good topic and I would like others to jump into discussion with their thoughts.
In my Opinion , DI and IOC are two different things. DI is a Injecting dependanices.
Suppose if I have a Segment Object which depends on two Point objects, Two point objects will be created and instantiated seperately, and can be injected to segment object.
This is injecting DEPENDANCIES (Two Point objects) into the dependant object(Segment object) ,which we as the application programmers would have done manually which is DI but not IOC (i.e. Flow is straight.(Application to framework))
But in Spring, since it is a framework or Container who does that job of injecting dependancies (DI) and not us, The flow of control is reversed, (Framework to Application) it is DI with IOC.
It is IOC not because of DI, but because flow of control is reversed.
However, When we talk about servlet. It is the servlet container that loads and instantiates servlets, but since it is independant servlet and has no depandancies to be injected, there is no DI, but since it is not us and it is the servlet container which instanciates and loads the servlets, the flow is reversed(i.e. Framework to Application) and hence it is IOC (IOC without DI)
I Hope I am correct and explanation is understandable. Please correct me if I am wrong anywhere.
Regards,
-Pankaj
Thanks for detailed comment. I appreciate it. In a sense you are right. IOC also helps in creating executable components without much details of background infrastructure. A valid point can be make in your case when servlet container provides advanced capabilities to servlet e.g. thread management, session handling and much more. So, servlets can be argued as IOC as well. I agree on this with you.
In fact IOC is much broader term and can include anywhere control of execution is put at separate place, away from executables.
With or without DI?? I really doubt myself. Basically we provide servlet mappings in web.xml. Should we consider them as DI? My take is YES. What you think?
Considering Servlets as DI, I think, Container just take lookup of Servlets in web.xml and instantiates the mapped servlet. But I think Container does not Inject any dependancies in the servlets?
If the container would have injected any Objects to servlets, It would have been DI (DI with IOC)
Is it that, Servlet object is dependant on other objects and servlets cannot be formed without injecting those dependancies? No right? Servlets are created by the container without injecting anything hence it is IOC without DI.
If the servlet object would have been dependant on any object, and those objects would have been injected by Container like ( Segment object has to have 2 point objects, i.e Segment object is completely dependant on Point objects, ) then it would have been a DI, (DI with IOC.) which is not the case.?
Even in Case of advanced capabilities the container does not have to inject any resources to servlet, Servlet is managed by container, but container does not have to inject anything to servlet instance, to form servlet, right? Hence It is not DI. but IOC.
Summary:
IOC- Flow of control is from Container to application.
DI- If One object is dependant on the other and if other object needs to be injected to that object,
IOC without DI- Flow of control is from Container to application but object is not dependant on the other and hence no need to inject dependancies. Container just instantiates the object without doing any dependancy Injection.
DI without IOC- If One object is dependant on the other and if other object needs to be injected to that object, If this process is done by the application directly and no container is involved, it is DI without IOC,
IOC With DI- – If One object is dependant on the other and if other object needs to be injected to that object, If this process is done by the container, The flow of control is reversed, hence it is IOC with DI,
Hope I am right and this clears the concept. Correct me if I am wrong.
Regards,
-Pankaj.
Hmm.. Make sense. Thanks for your time to write all this. It will help us all..
Hi ,
Thank you for this discussion, this really helped to clearly understand this concept.
Great Pankaj, you cleared my doubts
Nice blog lokesh…Every time before going to interview am referring to this site only..
Thanx for sharing your knowledge
I want to learn spring with web services, can you provide the example on this
https://howtodoinjava.com/spring-boot/spring-boot-rest-controller-example/