자바 기반의 경량 웹 프레임워크로, 효율적인 웹 애플리케이션 개발을 돕는 도구
POJO 기반으로 구성되어 있고, DI와 AOP, MVC 구조 등을 지원해서 유연하고 확장성 높은 개발이 가능
객체 간의 의존 관계를 외부에서 주입하는 방식
개발자가 직접 객체를 생성하지 않고, 필요한 객체를 Spring이 알아서 주입
→ 유지보수성, 테스트 용이성이 좋아짐
// 예시
@Autowired
private UserService userService; // Spring이 주입해줌
"객체를 관리하고 의존성을 주입해주는 IoC(Inversion of Control) 컨테이너"
스프링에서는 개발자가 직접 객체를 new로 생성하고 의존성을 설정X
→ 객체를 대신 만들어주고, 서로 연결해주고, 잘 관리해주는 역할
@Autowired, 생성자 주입 등)인터페이스 & 구현 클래스
public interface Dao {
void insertBoard();
}
public class OracleDao implements Dao {
public void insertBoard() {
System.out.println("OracleDao InsertBoard() 호출");
}
}
서비스 클래스
public class WriteService {
private Dao dao;
private MySql mySql;
// 생성자 주입
public WriteService(Dao dao, MySql mySql) {
this.dao = dao;
this.mySql = mySql;
}
public void insertService() {
System.out.println("WriteService insertService() 호출");
dao.insertBoard();
mySql.printMySql();
}
}
MySql 클래스
public class MySql implements Dao{
public void insertBoard() {
System.out.println("MySql InsertBoard() 호출");
}
}
Main 실행 클래스
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new GenericXmlApplicationContext(resource);
WriteService service = (WriteService)factory.getBean("writeService");
service.insertService();
XML 설정 파일 (applicationContext.xml)
<bean id="oracleDao" class="kosa.di.OracleDao"/>
<bean id="mySql" class="kosa.di.MySql"/>
<bean id="writeService" class="kosa.di.WriteService">
<constructor-arg ref="oracleDao"/>
<constructor-arg ref="mySql"/>
</bean>
WriteService.java 수정
public class WriteService {
private Dao dao;
public void setDao(Dao dao) {
this.dao = dao;
}
public void insertService() {
System.out.println("WriteService insertService() 호출");
dao.insertBoard();
}
}
applicationContext.xml 수정
<bean id="oracleDao" class="kosa.di.OracleDao"/>
<bean id="mySql" class="kosa.di.MySql"/>
<bean id="writeService" class="kosa.di.WriteService">
<property name="dao" ref="oracleDao"/>
<property name="mySql" ref="mySql"/>
</bean>
개념 요약
@Autowired를 사용하면 XML 설정 없이도 Spring이 자동으로 의존성 주입을 해줌.@Component, @Service, @Repository , @Controller 어노테이션이 있는 클래스들 객체 생성public interface Dao {
void insertBoard();
}
@Repository
public class OracleDao implements Dao {
public void insertBoard() {
System.out.println("OracleDao InsertBoard() 호출");
}
}
MySql.java
@Repository
public class MySql implements Dao{
public void insertBoard() {
System.out.println("MySql InsertBoard() 호출");
}
}
WriteService.java (어노테이션 방식)
@Service
public class WriteService {
@Autowired
private Dao dao;
public void insertService() {
System.out.println("WriteService insertService() 호출");
dao.insertBoard();
}
}
💡 주입 방식:
@Autowired를 필드에 붙이면 자동 주입
상황 결과 Dao구현체가 1개@Autowired만 써도 주입 OKDao구현체가 2개 이상@Autowired만 쓰면 오류 발생이럴 땐? @Qualifier("bean이름")을 써서 명확히 지정
applicationContext.xml 수정 (annotation-scan)
<context:component-scan base-package="kosa.di" />
패키지 단위 객체들(클래스들) 일괄적으로 생성!
기본적으로 클래스이름이 id이다. ( 첫자는 소문자 )
| 항목 | XML 기반 DI | Annotation 기반 DI |
|---|---|---|
| 설정 방법 | <bean> 태그로 명시적 설정 | 클래스에 @Component 등 사용 |
| 유지보수 | 설정 분리로 명확함 | 코드와 설정이 가까워 관리 용이 |
| 가독성 | 설정 파일 커질 수 있음 | 코드 자체에서 구조 파악 가능 |
| 유연성 | 다양한 설정을 외부에서 컨트롤 가능 | 컴포넌트 스캔 범위 안에서만 적용됨 |
| 추천 상황 | 외부 설정 관리 필요 시 | 코드 기반 프로젝트, 간단한 프로젝트 |
src/
└─ kosa/
└─ di/
├─ Dao.java
├─ OracleDao.java (→ @Repository)
├─ MySql.java (→ @Component)
├─ WriteService.java (→ @Service, @Autowired)
└─ Main.java (→ context load)
ApplicationContext context = new AnnotationConfigApplicationContext("kosa.di");
WriteService service = context.getBean(WriteService.class);
service.insertService();
AnnotationConfigApplicationContext 사용 시 applicationContext.xml 없이도 동작 가능.
WriteService라는 객체를 생성하고, 그 안에서 사용하는 Dao 객체(여기선 OracleDao)도 함께 스프링이 관리하게 만드는 것.
Factory 클래스 — 설정 클래스 (@Configuration + @Bean)@Configuration
public class Factory {
@Bean
public Dao oracleDao() {
return new OracleDao();
}
@Bean
public WriteService writeService() {
return new WriteService();
}
}
@Configuration: 이 클래스는 설정 정보를 담은 클래스임을 의미.@Bean: 스프링 컨테이너에 등록될 객체(Bean)를 정의.oracleDao() → OracleDao 객체를 Bean으로 등록.writeService() → WriteService 객체를 Bean으로 등록.하지만 여기서 중요한 포인트는 WriteService가 Dao를 직접 주입받고 있지 않다는 거야. 즉, WriteService 내부에서 Dao를 사용하는 방식이 명확하지 않으면 의존성 주입은 안 일어남.
@Bean
public WriteService writeService() {
return new WriteService(oracleDao());
} 혹은 @Autowired 등을 이용해서 필드나 생성자에 명시적으로 의존성을 표시해야 함.Main 클래스 — 스프링 컨테이너 초기화ApplicationContext factory = new AnnotationConfigApplicationContext(Factory.class);
WriteService service = (WriteService)factory.getBean("writeService");
service.insertService();
AnnotationConfigApplicationContext: 자바 기반 설정 파일(Factory.class)을 읽는 스프링 컨테이너.getBean("writeService"): 스프링 컨테이너에 등록된 writeService Bean을 꺼냄.insertService(): WriteService 객체의 메서드를 실행함.Main
└── ApplicationContext (Spring Container)
├── WriteService Bean
│ └── Dao (OracleDao) Bean ← 이 부분이 제대로 연결되어야 함
└── Dao (OracleDao) Bean