Complete Spring Framework 4 Tutorial with Examples and Interview Tips
✅ 1. What is Spring Framework?
Spring is a powerful, lightweight framework for building Java enterprise applications. It promotes loose coupling through Dependency Injection (DI) and offers powerful integrations for web apps, data access, security, AOP, and more.
🔑 Core Features:
- IoC Container (Dependency Injection)
- AOP (Aspect-Oriented Programming)
- Spring MVC (Web framework)
- Spring JDBC/ORM
- Transaction Management
- Spring Security
- Spring Testing
✅ 2. Dependency Injection (DI) in Spring
➤ What is Dependency Injection?
DI is a design pattern that allows an object to receive its dependencies from an external source rather than creating them itself.
✨ Benefits:
- Loose coupling
- Better testability
- More maintainable code
➤ DI with XML Configuration
📄 beans.xml:
Explanation:
- Declares 2 beans.
employeeServicedepends onemployeeDao.<property>injectsemployeeDaointoemployeeServiceusing its setter method.
<bean id="employeeDao" class="com.app.EmployeeDao" />
<bean id="employeeService" class="com.app.EmployeeService">
<property name="employeeDao" ref="employeeDao" />
</bean>
📄 EmployeeService.java:
Explanation:
setEmployeeDao()is a setter.- Spring calls this and injects the dependency defined in
beans.xml.
public class EmployeeService {
private EmployeeDao employeeDao;
public void setEmployeeDao(EmployeeDao dao) {
this.employeeDao = dao;
}
}
🔹 Annotation-Based DI
📄 EmployeeDao.java
@Component
public class EmployeeDao {}
📄 EmployeeService.java
@Service
public class EmployeeService {
@Autowired
private EmployeeDao employeeDao;
}
📄 AppConfig.java
@Configuration
@ComponentScan("com.app")
public class AppConfig {}
Explanation:
@Component/@Service: Marks the class as a Spring-managed bean.@Autowired: Automatically wiresEmployeeDaointoEmployeeService.@ComponentScan: Scans the package for Spring annotations.
✅ 3. Bean Scopes in Spring
| Scope | Description |
|---|---|
| singleton | One shared instance per Spring container |
| prototype | New instance each time it’s requested |
| request | One per HTTP request (Web only) |
| session | One per session (Web only) |
📄 Example:
Explanation:
@Component: Declares the class as a bean.@Scope("prototype"): Spring will create a new instance every time this bean is requested (instead of sharing the same one).
@Component
@Scope("prototype")
public class MyBean {}
✅ 4. Aspect-Oriented Programming (AOP)
➤ What is AOP?
AOP allows you to define cross-cutting concerns (like logging, security, transactions) separately from business logic.
📄 Example: Logging Aspect
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.app.service.*.*(..))")
public void log(JoinPoint jp) {
System.out.println("Method called: " + jp.getSignature());
}
}
Key Annotations:
@Aspect@Before,@After,@Around@EnableAspectJAutoProxy
Explanation:
@Aspect: Declares this class as an AOP aspect.@Before(...): Executes before any method incom.app.service.*package.JoinPoint: Gives method metadata at runtime.- This is commonly used for logging, auditing, security.
✅ 5. Spring JDBC (with JdbcTemplate)
➤ What is JdbcTemplate?
A helper class that simplifies database operations.
📄 UserDao.java:
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbc;
public void save(User u) {
jdbc.update("INSERT INTO users(name,email) VALUES (?,?)", u.getName(), u.getEmail());
}
}
📄 DataSource Config:
@Bean
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUrl("jdbc:mysql://localhost/test");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
Explanation:
JdbcTemplatehandles low-level JDBC tasks (connection, statement, exception).jdbc.update(...): Runs a SQL update/insert.?: Placeholder for values.DataSource: Provides database connection details.
✅ 6. Spring MVC – Web Framework
➤ DispatcherServlet Flow:
Request → DispatcherServlet → Controller → ViewResolver → JSP
📄 HomeController.java:
@Controller
public class HomeController {
@RequestMapping("/hello")
public String hello(Model model) {
model.addAttribute("msg", "Hello from Spring!");
return "hello";
}
}
📄 hello.jsp:
<h2>${msg}</h2>
Explanation:
@Controller: Marks the class as a Spring MVC controller.@RequestMapping("/hello"): Maps URL/helloto this method.Model model: Sends data to the view.model.addAttribute(...): Adds data to be shown in JSP.- JSP renders the
msgvalue from the controller.
✅ 7. Form Handling in Spring MVC
📄 User.java:
public class User {
private String name;
private String email;
// Getters and setters
}
📄 UserController.java:
@GetMapping("/register")
public String showForm(Model model) {
model.addAttribute("user", new User());
return "register";
}
@PostMapping("/save")
public String save(@ModelAttribute("user") User user) {
System.out.println(user.getName() + " - " + user.getEmail());
return "result";
}
📄 register.jsp:
<form action="save" method="post">
Name: <input name="name" type="text"/><br/>
Email: <input name="email" type="text"/><br/>
<input type="submit"/>
</form>
Explanation:
@ModelAttribute("user"): Binds form fields toUserobject.GET /register: Shows form with an emptyUserobject.POST /save: Submits form, Spring populates theUserobject.
✅ 8. Spring Transaction Management
📄 BankService.java:
@Service
public class BankService {
@Autowired
private AccountDao dao;
@Transactional
public void transfer(String fromAcc, String toAcc, double amount) {
dao.withdraw(fromAcc, amount);
dao.deposit(toAcc, amount);
}
}
💡 If any method fails, the transaction is rolled back.
Explanation:
@Transactional: Spring wraps this method in a transaction.- If
withdrawsucceeds butdepositfails, everything rolls back. - Ensures atomicity and consistency.
✅ 9. Spring Security (In-Memory Auth)
📄 SecurityConfig.java:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("{noop}1234").roles("ADMIN");
}
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().formLogin();
}
}
🔒 Add spring-security-web and spring-security-config to your dependencies.
Explanation:
@EnableWebSecurity: Enables Spring Security.inMemoryAuthentication(): Hardcoded login (admin/1234).{noop}: Tells Spring the password is plaintext (for demo only).http.authorizeRequests(): Protects all endpoints — forces login.
✅ 10. Spring Profiles (For Environment Configs)
📄 DevConfig.java:
@Configuration
@Profile("dev")
public class DevConfig {
@Bean
public DataSource devDataSource() { ... }
}
📄 ProdConfig.java:
@Configuration
@Profile("prod")
public class ProdConfig {
@Bean
public DataSource prodDataSource() { ... }
}
📄 application.properties:
propertiesCopyEditspring.profiles.active=dev
Explanation:
@Profile("dev"): Used only whendevprofile is active.- Switch between environments without changing code.
✅ 11. Spring Testing with JUnit
📄 UserServiceTest.java:
Explanation:
@RunWith: Integrates Spring context with JUnit.@ContextConfiguration: Loads beans fromAppConfig.@Autowired: Injects the bean under test.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testSave() {
User u = new User("Test", "[email protected]");
userService.save(u);
}
}
✅ 12. Spring Best Practices
| Best Practice | Why? |
|---|---|
| Use constructor injection | Promotes immutability and testing |
| Keep controller thin, service rich | Follows separation of concerns |
| Avoid field injection if possible | Harder to test |
| Externalize configuration | Easier environment management |
Use @Service, @Repository properly | Helps AOP and Spring’s stereotypes |
Use @Transactional at service layer | Controls transaction scope cleanly |
🧠 Spring Interview Q&A Summary
| Question | Answer |
|---|---|
| What is Spring? | A modular Java framework for enterprise applications |
| What is DI? | Injecting dependencies instead of creating them manually |
| Singleton vs Prototype? | Singleton = 1 bean instance, Prototype = new bean every time |
| What is AOP? | Separates cross-cutting concerns |
Purpose of @Transactional? | Rollback changes if something fails |
Difference: @Component vs @Service? | @Service is semantic for business layer |
| What is Spring MVC flow? | DispatcherServlet → Controller → ViewResolver → JSP |
| JdbcTemplate benefits? | Simplifies DB access |
| XML vs Java Config? | Java Config is type-safe and more modern |
| Profiles use case? | Environment-specific beans (dev/test/prod) |
✅ Additional Concepts of Spring
🔹 1. Bean Lifecycle Callbacks
- init-method / destroy-method in XML
@PostConstructand@PreDestroyin annotation config
📄 Example:
@Component
public class MyBean {
@PostConstruct
public void init() {
System.out.println("Bean initialized");
}
@PreDestroy
public void destroy() {
System.out.println("Bean destroyed");
}
}
📌 Useful for initializing resources or cleanup.
🔹 2. FactoryBean Interface
Allows more complex logic when creating beans.
📄 Example:
public class CarFactory implements FactoryBean<Car> {
public Car getObject() {
return new Car(); // Complex creation logic
}
public Class<?> getObjectType() {
return Car.class;
}
}
Used when bean creation needs dynamic logic.
🔹 3. ApplicationContext vs BeanFactory
| Feature | BeanFactory | ApplicationContext |
|---|---|---|
| Lazy loading | Yes | No (eager by default) |
| Event handling | No | Yes |
| Internationalization | No | Yes |
Use
ApplicationContextin most cases.
🔹 4. Spring Events
Spring lets beans communicate via events.
📄 Example:
public class MyEvent extends ApplicationEvent {
public MyEvent(Object source) {
super(source);
}
}
@Component
public class MyListener implements ApplicationListener<MyEvent> {
public void onApplicationEvent(MyEvent event) {
System.out.println("Event received!");
}
}
📌 Good for decoupled communication within app.
🔹 5. Custom Qualifiers
When multiple beans of the same type exist.
📄 Example:
@Qualifier("mysqlRepo")
@Autowired
private UserRepository repo;
Or define a custom qualifier:
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, PARAMETER})
public @interface MyRepo {}
🔹 6. BeanPostProcessor
Custom logic before and after bean initialization.
📄 Example:
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) {
System.out.println("Before Init: " + name);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) {
System.out.println("After Init: " + name);
return bean;
}
}
🔹 7. Property Placeholder / External Properties
Reading values from .properties files.
📄 Example:
db.url=jdbc:mysql://localhost/test
📄 Java Config:
@PropertySource("classpath:db.properties")
public class AppConfig {
@Value("${db.url}")
private String url;
}
🔹 8. @Required Annotation
Forcing Spring to inject a property (setter-based injection).
@Required
public void setName(String name) {
this.name = name;
}
💡 Deprecated in later Spring versions — use constructor injection.
🔹 9. Spring Integration with Hibernate
Using HibernateTemplate, LocalSessionFactoryBean, or Spring ORM.
📄 XML example:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
...
</bean>
10. 🧠 SpEL (Spring Expression Language)
. @value
@Value("#{2 * 2}")
private int value;
- @Scheduled
Scheduled(fixedRate = 5000)
public void poll() {
System.out.println("Polling...");
}
- @Cacheable
@Cacheable("users")
public User findById(String id) {
...
}
