Here’s a recommended simple layout (non-Maven, manual JAR setup) for a Spring core project:
MySpringProject/
│
├── lib/ ← folder to hold Spring and other JARs
│ ├── spring-core.jar
│ ├── spring-beans.jar
│ ├── spring-context.jar
│ └── … (other dependencies)
│
├── src/ ← your Java source code
│ ├── com/
│ │ └── example/
│ │ ├── AppMain.java
│ │ ├── service/
│ │ │ ├── MyService.java
│ │ │ └── impl/ …
│ │ └── config/
│ │ └── AppConfig.java
│ └── …
│
├── resources/ ← (optional) for config XML, property files
│ └── applicationContext.xml
│
└── README.md
- 
Create the folders
- In your file system (or via IntelliJ), create 
MySpringProject, thenlib,src,resources, etc. - Inside 
src, create your package hierarchy (e.g.com.example.service,com.example.config, etc.) 
 - In your file system (or via IntelliJ), create 
 - 
Open the project in IntelliJ
File → Open…→ select theMySpringProjectfolder.
 - 
Add the JAR dependencies
- Right-click on the project → Open Module Settings (or press 
F4). - Under “Modules” → your module → tab Dependencies.
 - Click the + icon → JARs or directories → navigate to and select all JARs in 
lib/. - Choose whether to add them as Compile scope (usually yes).
 - IntelliJ will include those JARs on the module classpath.
 
 - Right-click on the project → Open Module Settings (or press 
 - 
Mark source / resource roots
- In the Project view, right-click the 
srcfolder → Mark Directory as → Sources Root (turns it blue). - Right-click 
resources→ Mark Directory as → Resources Root (turns it a different color, e.g. light green). - This tells IntelliJ where to look for Java classes and non-Java resources.
 
 - In the Project view, right-click the 
 - 
Verify classpath and build
- Try creating a simple 
AppMain.javawithpublic static void main(...)and compile/run. - The JARs in 
lib/should be recognized (e.g., importorg.springframework.context.ApplicationContextshould resolve). 
 - Try creating a simple 
 
That’s the basic manual setup. (In real projects, using Maven or Gradle makes dependency management easier, but this is good for a learning setup.)
Below is a conceptual summary + code examples to illustrate how DI and Autowiring work, following the tutorial you referenced (which covers Spring IoC, DI, and autowiring). :contentReference[oaicite:0]{index=0}
- Inversion of Control (IoC) means that the control of creating and managing dependencies is inverted: instead of your code instantiating dependencies, you delegate that to a container (Spring).
 - Dependency Injection (DI) is a pattern that implements IoC: components declare their dependencies (via constructor, setter, or fields), and the container injects those dependencies at runtime.
 
Spring supports multiple styles:
- Constructor-based DI
 - Setter-based DI
 - Field injection (via 
@Autowired) - Autowiring by name / by type / by constructor (automatically resolving dependencies)
 
Suppose you have:
<!-- resources/applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       … other namespaces …>
  
  <bean id="myService" class="com.example.service.impl.MyServiceImpl">
    <property name="myDao" ref="myDao" />
  </bean>
  <bean id="myDao" class="com.example.dao.impl.MyDaoImpl"/>
  
</beans>And Java:
package com.example.service;
public interface MyService {
    void perform();
}
package com.example.service.impl;
import com.example.dao.MyDao;
public class MyServiceImpl implements MyService {
    private MyDao myDao;
    public void setMyDao(MyDao myDao) {
        this.myDao = myDao;
    }
  
    @Override
    public void perform() {
        myDao.save();
    }
}
Here, Spring container reads the XML, sees that myService bean has a property named myDao, looks for bean myDao, and invokes setMyDao(...) on the MyServiceImpl instance to inject dependency.
Modern approach uses @Configuration, @Bean, @Component, @Autowired, etc.
package com.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
    // You can also define explicit beans here if needed.
}
package com.example.service;
public interface MyService {
    void perform();
}
package com.example.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.dao.MyDao;
@Service
public class MyServiceImpl implements MyService {
    // Option A: field injection (not always recommended)
    @Autowired
    private MyDao myDao;
    @Override
    public void perform() {
        myDao.save();
    }
}
package com.example.dao.impl;
import org.springframework.stereotype.Repository;
import com.example.dao.MyDao;
@Repository
public class MyDaoImpl implements MyDao {
    @Override
    public void save() {
        System.out.println("Data saved...");
    }
}
And the main entry:
package com.example;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.example.config.AppConfig;
import com.example.service.MyService;
public class AppMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx =
                new AnnotationConfigApplicationContext(AppConfig.class);
        
        MyService svc = ctx.getBean(MyService.class);
        svc.perform();
        ctx.close();
    }
}
Here’s how it works, step by step:
- 
You bootstrap Spring with AnnotationConfigApplicationContext(AppConfig.class).
 - 
@ComponentScan tells Spring to scan com.example package for components annotated with @Component, @Service, @Repository, @Controller, etc.
 - 
Spring finds MyServiceImpl and MyDaoImpl and instantiates beans for them.
 - 
It sees @Autowired on myDao field in MyServiceImpl → it finds a matching bean of type MyDao (MyDaoImpl) and injects it.
 - 
When you call ctx.getBean(MyService.class), you get the bean instance with its dependency already injected.
 
The tutorial mentions that Spring supports different autowiring strategies: by name, by type, constructor, etc. smartprogramming.in
- 
byName: Spring looks for a bean whose name matches the property name.
 - 
byType: Spring looks for a bean whose type matches the property type.
 - 
constructor: Spring uses the constructor that best matches the bean definitions.
 - 
autodetect: Spring first tries constructor, then setter.
 
With annotations, default is by type (i.e. @Autowired injects by type). If multiple beans of same type exist, you can qualify with @Qualifier:
@Autowired
@Qualifier("myDaoImpl")
private MyDao myDao;
You can also use @Primary on one bean to mark it as default when multiple candidates exist.
- 
Bean scope by default is singleton (one instance per container)
 - 
Other scopes: prototype, request, session, etc.
 - 
Spring also allows lifecycle callbacks (@PostConstruct, @PreDestroy) etc.