DI(Dependency Injection): 의존성 주입
클래스가 다른 클래스의 메서드를 사용하는 것
ex) MemberRegisterService 클래스가 selectByEmail() 메서드를 사용하기 위해 MemberDao 클래스에 의존
생성자 방식
public class MemberRegisterService {
private MemberDao memberDao;
// 캐시 적용 Dao
// MemberDao를 상속받음
// public class CachedMemberDao extends MemberDao {
private MemberDao memberDao = new CachedMemberDao();
// 생성자를 통해 의존 객체를 주입받음
public MemberRegisterService(MemberDao memberDao) {
// 주입받은 객체를 필드에 할당
this.memberDao = memberDao;
}
public Long regist(RegisterRequest req) {
// 주입받은 의존 객체의 메서드를 사용
Member member = memberDao.selectByEmail(req.getEmail());
...
memberDao.insert(newMember);
return newMember.getId();
}
}
세터 메서드 방식
- 의존 객체를 주입받는 코드를 세터 메서드로 작성
- 의존을 주입하는 설정 코드를 import받는 클래스에 추가
범위 | 설명 |
singleton | 스프링 컨테이너당 하나의 인스턴스 빈만 생성(default) |
prototype | 컨테이너에 빈을 요청할 때마다 새로운 인스턴스 생성 |
request | HTTP Request별로 새로운 인스턴스 생성 |
session | HTTP Session별로 새로운 인스턴스 생성 |
//Service
import org.springframework.stereotype.Component;
@Component("service")
@Scope("singleton")
public class ServiceImpl implements Service {
@Override
public int test(Dto dto) {
return 0;
}
}
@Bean 설정
XML
- XML문서 형태로 빈의 설정 메타 정보를 기술
- 단순하며 사용하기 쉬움
- <bean> 태그를 이용해 세밀한 제어 가능
- 사용하지 않음
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="service" class="com.test.service" scope="prototype" init-method="init">
<property name="dao" ref="dao"/>
</bean>
// 위와 아래의 코드가 같음
<bean id="service" class="com.test.service" scope="prototype" init-method="init" p:dao-ref="d"/>
</beans>
Annotation
- 애플리케이션의 규모가 커지고 빈의 개수가 많아질 경우 XML 파일을 관리하는 것이 번거로움
- 빈으로 사용될 클래스에 특별한 annotation을 부여해 주면 자동으로 빈 등록 가능
- "오브젝트 빈 스캐너"로 "빈 스캐닝"을 통해 자동 등록
>> 빈 스캐너는 기본적으로 클래스 이름의 첫 글자만 소문자로 바꾼 것을 사용
- 무조건 Annotation 사용
@Component
public class ServiceImpl implements Service {
@Autowired
private TestDao dao;
@Override
public int test(Dto dto) {
return dao.test(dto);
}
}
- 반드시 component-scan을 설정해야 한다
//application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.test.*"></context:component-scan>
</beans>
Stereotype annotation 종류
- 빈 자동등록에 사용할 수 있는 annotation
>> 계층별로 빈의 특성이나 종류를 구분
>> AOP Pointcut 표현식을 사용하면 특정 annotation이 달린 클래스만 설정 가능
>> 특정 계층의 빈에 부가기능을 부여
Stereotype | 적용 대상 |
@Repository | Data Access Layer의 DAO 또는 Repository 클래스에 사용 DataAccessException 자동변환과 같은 AOP의 적용 대상을 선정하기 위해 사용 |
@Service | Service Layer의 클래스에 사용 |
@Controller | Presentation Layer의 MVC Controller에 사용 스프링 웹 서블릿에 의해 웹 요청을 처리하는 컨트롤러 빈으로 설정 |
@Component | 위의 Layer 구분을 적용하기 어려운 일반적인 경우에 설정 |
@Bean 의존 관계 설정
- 멤버변수에 직정 정의하는 경우 setter method를 만들지 않아도 됨
annotation | 설명 |
@Resource | Spring 2.5부터 지원 멤버변수, setter method에 사용 가능 타입에 맞춰서 연결 |
@Autowired | Spring 2.5부터 지원 Spring에서만 사용 가능 Required 속성을 통해 DI여부 조정 멤버변수, setter, constructor, 일반 method 사용 가능 타입에 맞춰서 연결 |
@Inject | Spring 3.0부터 지원 Frameword에 종속적이지 않음 Javax.inject-x.x.x.jar 필요 멤버변수, sette, constructor, 일반 method 사용 가능 이름으로 연결 |
@Resource
- 멤버 변수
- setter method
//멤버 변수에 @Resource
@Component
public class ServiceImpl implements Service {
@Resource(name="tdao") // 동일한 타입의 빈이 여러 개일 경우 name을 통하여 구분
private TestDao dao;
@Override
public int test(Dto dto) {
return dao.test(dto);
}
}
// setter method에 @Resource
@Component
public class ServiceImpl implements Service {
private TestDao dao;
@Resource(name="tdao")
public void setDao(Dao dao) {
this.dao = dao;
}
@Override
public int test(Dto dto) {
return dao.test(dto);
}
}
@Autowired
- 생성자
- constructor
- 일반 method
- 스프링 자동 주입 기능
- 해당 타입의 빈을 찾아서 필드에 할당
//생성자에 @Autowired
@Component
public class ServiceImpl implements Service {
TestDao testDao;
AdminDao adminDao;
public ServiceImpl() {}
@Autowired //생성자가 여러개일 경우에는 하나만 사용 가능
//동일한 타입의 bean이 여러개일 경우에는 @Qualifier("name")으로 식별한다
public ServiceImpl(@Qualifier("tdao") TestDao testDao,
@Qualifier("adao") AdminDao adminDao) {
super();
this.testDao = testDao;
this.adminDao = adminDao;
}
@Override
public int test(TestDto testDto) {
return testDao.test(testDto);
}
}
//constructor에 @Autowired
@Component
public class ServiceImpl implements Service {
@Autowired
@Qualifier("tdao")//동일 타입이 여러개일 경우
TestDao testDao;
@Autowired
@Qualifier("adao")
AdminDao adminDao;
public ServiceImpl() {}
@Override
public int test(TestDto testDto) {
return testDao.test(testDto);
}
}
//일반 method에 @Autowired
@Component
public class ServiceImpl implements Service {
TestDao testDao;
AdminDao adminDao;
public ServiceImpl() {}
@Autowired //생성자가 여러개일 경우에는 하나만 사용 가능
//동일한 타입의 bean이 여러개일 경우에는 @Qualifier("name")으로 식별한다
public void initService(@Qualifier("tdao") TestDao testDao,
@Qualifier("adao") AdminDao adminDao) {
this.testDao = testDao;
this.adminDao = adminDao;
}
@Override
public int test(TestDto testDto) {
return testDao.test(testDto);
}
}
@Autowired
- 의존 자동 주입
- 생성자 방식과 set 메서드 방식 둘 다 @Autowired를 붙일 수 있다
- 설정 클래스에서 세터 메서드를 이용해 의존을 주입해도, 해당 세터 메서드에 @Autowired 애노테이션이 붙어 있으면 자동 주입을 통해 일치하는 빈을 주입한다
@Qualifier("printer")
- 자동 주입 가능한 빈이 두 개 이상일 때 사용
- 해당 빈의 한정 값으로 "printer"를 지정
- 지정한 한정 갑은 @Autowired 애노테이션에서 자동 주입할 빈을 한정할 때 사용
@Nullable
- 일치하는 빈이 존재하지 않을 때 null을 인자로 준다
- 일치하는 빈이 존재하지 않을 때 값 할당 자체를 하지 않는 @Autowired(required = false)와 다름
'프로그래밍 > SPRING' 카테고리의 다른 글
06. AOP (0) | 2022.04.26 |
---|---|
05. DI 적용 (0) | 2022.04.24 |
03. Spring Framework (0) | 2022.04.23 |
02. IoC & Container (0) | 2022.04.17 |
01. Spring (0) | 2022.04.12 |