정의:
DI는 클래스의 의존성을 해당 클래스가 직접 처리하는 대신, Spring IoC 컨테이너가 생성 및 관리하도록 위임하는 디자인 패턴입니다. 이를 통해 클래스와 의존성 간의 결합도가 낮아지고, 시스템이 더 모듈화되고 테스트하기 쉬워집니다.
IoC(Inversion of Control, 제어의 역전):
객체의 생성, 관리, 소멸 등을 프레임워크가 담당하며, 개발자는 이러한 작업에서 벗어날 수 있습니다.
ApplicationContext:
Spring 컨테이너로, 설정을 제공하고, 빈(bean)을 관리하며 의존성을 해결합니다. 주요 예:
AnnotationConfigApplicationContextGenericXmlApplicationContextBean:
Spring 컨테이너에 의해 관리되는 객체입니다. 빈은 어노테이션(@Component, @Service, @Repository, @Controller) 또는 설정 클래스를 통해 정의됩니다.
@Autowired를 사용하여 의존성을 private 필드에 직접 주입합니다.예제:
@Service("writeAction")
public class WriteAction {
@Autowired
private BoardDAO dao; // 컨테이너에 의해 주입됨
public WriteAction() {
System.out.println("WriteAction 생성자: dao = " + dao);
}
public void getDAO() {
System.out.println("주입된 DAO: " + dao);
}
}
예제:
@Service("writeAction")
public class WriteAction {
private final BoardDAO dao;
@Autowired
public WriteAction(BoardDAO dao) {
this.dao = dao;
System.out.println("생성자 주입: dao = " + dao);
}
}
예제:
@Service("writeAction")
public class WriteAction {
private BoardDAO dao;
@Autowired
public void setDao(BoardDAO dao) {
this.dao = dao;
System.out.println("세터 주입: dao = " + dao);
}
}
@Qualifier를 사용하여 특정 빈을 지정합니다.예제:
@Bean("oracle")
public OracleDatabaseDAO oracleDatabaseDAO() {
return new OracleDatabaseDAO();
}
@Service
public class DatabaseService {
@Autowired
@Qualifier("oracle") // 특정 빈 이름을 명시적으로 지정
private DatabaseDAO databaseDAO;
public List<String> getList() {
return databaseDAO.list();
}
}
Spring은 빈의 라이프사이클을 관리합니다:
@PostConstruct 또는 사용자 정의 초기화 메서드가 호출됩니다.@PreDestroy 또는 사용자 정의 소멸 메서드).Spring Boot에서는 ApplicationContext가 자동으로 생성되고 구성됩니다:
@SpringBootApplication이 이를 관리합니다.ctx.getBean()을 통해 빈을 가져오거나, 직접 @Autowired로 주입받을 수 있습니다.정의:
AOP는 로깅, 보안, 트랜잭션 관리와 같은 횡단 관심사를 모듈화합니다. 이를 통해 핵심 비즈니스 로직과 이러한 관심사를 분리하여 유지보수성을 향상시킵니다.
@Around, @Before, @After 등).@Aspect
@Configuration
public class BasicAdvice {
@Around("execution(public * say*(..))") // "say"로 시작하는 메서드에 적용
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("메서드 실행 전");
Object result = joinPoint.proceed();
System.out.println("메서드 실행 후");
return result;
}
}
Spring Boot에서는 AOP가 자동으로 활성화되며, @Aspect와 @EnableAspectJAutoProxy를 통해 Aspect를 감지합니다.
시나리오:
MySQLDatabaseDAO와 OracleDatabaseDAO.DatabaseService.구현:
1. 공통 인터페이스를 구현하는 DAO를 생성합니다.
public interface DatabaseDAO {
List<String> list();
}
public class MySQLDatabaseDAO implements DatabaseDAO {
@Override
public List<String> list() {
return Arrays.asList("Data 1", "Data 2");
}
}
public class OracleDatabaseDAO implements DatabaseDAO {
@Override
public List<String> list() {
return Arrays.asList("Data 3", "Data 4");
}
}
@Autowired와 @Qualifier를 사용하는 서비스 생성:
@Service
public class DatabaseService {
@Autowired
@Qualifier("oracle")
private DatabaseDAO databaseDAO;
public List<String> getList() {
return databaseDAO.list();
}
}
설정 클래스에서 빈을 정의합니다:
@Configuration
public class BeanConfig {
@Bean("mysql")
public MySQLDatabaseDAO mySQLDatabaseDAO() {
return new MySQLDatabaseDAO();
}
@Bean("oracle")
public OracleDatabaseDAO oracleDatabaseDAO() {
return new OracleDatabaseDAO();
}
@Bean
public DatabaseService service() {
return new DatabaseService();
}
}