출처: https://bumcrush.tistory.com/182 [맑음때때로 여름]

의존성 주입

 

 

Spring Framework가 지원하는 핵심 기능으로 객체 사이의 의존 관계가 객체 자신이 아닌 외부(조립기)에 의해 설정된다. 외부 조립기는 xml 설정 파일을 기반으로 의존을 설정한다.

 

package member.dao;
public interface Dao {
// public abstract void insert();
void insert();
void select();
void delete();
void update();
}
package member.dao;
public class MemberDao implements Dao {
@Override
public void insert() {
System.out.println("회원 정보 데이터베이스 저장");
}
@Override
public void select() {
System.out.println("회원 정보 검색");
}
@Override
public void delete() {
System.out.println("회원 정보 삭제");
}
@Override
public void update() {
System.out.println("회원 정보 수정");
}
}

 

 

생성자 타입의 주입방식

 

package member.service;
import member.dao.Dao;
public class MemberRegService implements MemberService {
// Dao dao = new MemberDao(); // 의존성이 높은 코드이므로 X
/* 생성자 방식 */
private Dao dao; // 주입받아야하는 참조변수
// 생성자를 통해서 Dao타입의 인스턴스를 주입받는다.
// Dao dao = new MemberDao(); -> 다형성.
public MemberRegService(Dao dao) {
this.dao = dao;
}
@Override
public Object process() {
System.out.println("MemberRegService 실행");
dao.insert();
return null;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- MemberDao를 Bean(인스턴스)으로 등록 -->
<bean
id="memberDao"
class="member.dao.MemberDao"
>
</bean>
<!-- MemberRegService bean으로등록 -->
<bean id="memberRegService"
class="member.service.MemberRegService">
<!-- <constructor-arg ref="memberDao"/> -->
<constructor-arg>
<ref bean="memberDao"/>
</constructor-arg>
</bean>
</beans>

 

 

프로퍼티 타입의 주입방식

 

package member.service;
import member.dao.Dao;
public class MemberInfoService implements MemberService{
/* 프로퍼티 타입 */
Dao dao;
// 프로퍼티 타입의 주입 방식 : setter 메소드 정의가 필요하다
public void setDao(Dao dao) {
this.dao = dao;
}
@Override
public Object process() {
System.out.println("MeberInfoService 실행");
dao.select();
return null;
}
}
<!-- 멤버인포서비스 Bean등록 -->
<bean id="memberInfoService" class="member.service.MemberInfoService">
<!-- <property name="dao" ref="memberDao"></property> -->
<property name="dao">
<ref bean="memberDao"/>
</property>

 

MemberMain 실행

package member.main;
import org.springframework.context.support.GenericXmlApplicationContext;
import member.service.MemberInfoService;
import member.service.MemberRegService;
public class MemberMain {
public static void main(String[] args) {
//1. Spring 컨테이너 생성
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");
//2. MemberRegService 객체가 필요
MemberRegService regService = ctx.getBean("memberRegService", MemberRegService.class);
//3. MemberRegService 프로세스 메서드 실행
regService.process();
//4. MemberinfoService 객체가 필요
MemberInfoService infoService = ctx.getBean("memberInfoService", MemberInfoService.class);
//5. MemberInfoService 프로세스 메서드 실행
infoService.process();
}
}

 

xml 설정파일

 

1. XML 네임스페이스를 이용한 프로퍼티 설정

<!-- 멤버인포서비스 Bean등록 -->
<bean id="memberInfoService" class="member.service.MemberInfoService">
<!-- <property name="dao" ref="memberDao"></property> -->
<property name="dao">
<ref bean="memberDao"/>
</property>
↓ 아래처럼 간결해짐
<!-- 프로퍼티 방식에서 p를 사용하면 속성을 사용하지 않고 한 줄 처리가 가능 -->
<!-- 멤버인포서비스 Bean등록 -->
<bean id="memberInfoService" class="member.service.MemberInfoService"
p:dao-ref="memberDao">
</bean>
</beans>

 

2. 의존관계 설정 : 임의 빈 객체 전달

<bean id="memberInfoService" class="member.service.MemberInfoService">
<!-- <property name="dao" ref="memberDao"></property> -->
<property name="dao">
<bean class="member.dao.MemberDao"/>
</property>

 

3. 여러개의 xml 사용 / 두 개 이상의 설정파일 사용하기 > import 이용

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:appCtx4_1.xml"/>
<import resource="classpath:appCtx4_2.xml"/>
</beans>

 

 

 

 

 

DI - 의존관계자동설정

 

 

 

 

빈 객체 범위

 

xml에서 scope 설정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- MemberDao를 Bean(인스턴스)으로 등록 -->
<bean
id="memberDao"
class="member.dao.MemberDao"
>
</bean>
<!-- MemberRegService bean으로등록 -->
<bean id="memberRegService"
class="member.service.MemberRegService"
scope="prototype"
>
<constructor-arg>
<ref bean="memberDao"/>
</constructor-arg>
</bean>
<!-- 멤버인포서비스 Bean등록 -->
<bean id="memberInfoService"
class="member.service.MemberInfoService"
scope="singleton">
<property name="dao">
<bean class="member.dao.MemberDao"/>
</property>
</bean>
</beans>
package member.main;
import org.springframework.context.support.GenericXmlApplicationContext;
import member.dao.Dao;
import member.service.MemberInfoService;
import member.service.MemberRegService;
public class MemberMain2 {
public static void main(String[] args) {
//1. Spring 컨테이너 생성
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx5.xml");
Dao dao1 = ctx.getBean("memberDao", Dao.class);
Dao dao2 = ctx.getBean("memberDao", Dao.class);
// 아무 처리도 하지않으면 기본적으로 싱글톤이다.
System.out.println("dao1참조변수 == dao2참조변수 ? " +(dao1==dao2));
//2. MemberRegService 객체가 필요
MemberRegService regService1 = ctx.getBean("memberRegService", MemberRegService.class);
MemberRegService regService2 = ctx.getBean("memberRegService", MemberRegService.class);
// 프로포타입이므로 false
System.out.println("regService1==regService2 ? " + (regService1==regService2));
//4. MemberinfoService 객체가 필요
MemberInfoService infoService1= ctx.getBean("memberInfoService", MemberInfoService.class);
MemberInfoService infoService2= ctx.getBean("memberInfoService", MemberInfoService.class);
// 싱글톤타입이므로 true > 둘의참조변수가같다
System.out.println("infoService1==infoService2 ? " + (infoService1==infoService2));
}
}

 

.

 

 

 

애노테이션 기반 설정

JDK5 버전부터 추가된 것으로 메타데이터를 XML등의 문서에 설정하는 것이 아니라 소스 코드에 “@애노테이션”의 형태로 표현하며 클래스, 필드, 메소드의 선언부에 적용 할 수 있는 특정 기능이 부여된 표현법이다. 프레임워크들이 활성화 되고 애플리케이션 규모가 커질수록 XML 환경 설정은 복잡해지는데, 이러한 어려움을 개선시키기 위하여 자바 파일에 애노테이션을 적용해서 코드를 작성함으로써 개발자가 설정 파일에 작업하게 될 때 발생시키는 오류의 발생 빈도를 낮춰주기도 한다.

 

 

Java 에서 이미 정의되어 있는 애노테이션


@Override - 메소드가 오버라이드 됐는지 검증.

                 부모 클래스 또는 구현해야 할 인터페이스에서 해당 메소드를 찾을 수 없다면 컴파일 오류. 
@Deprecated - 메소드를 사용하지 말도록 유도. 만약 사용한다면 컴파일 경고. 
@SuppressWarnings - 컴파일 경고를 무시. 
@SafeVarargs - 제너릭 같은 가변인자 매개변수를 사용할 때 경고를 무시.(자바7 이상) 
@FunctionalInterface - 람다 함수등을 위한 인터페이스를 지정.

                               메소드가 없거나 두 개 이상 되면 컴파일 오류.(자바 8이상)

 

 

@Autowired 애노테이션을 이용한 의존 자동 주입

 

 

xml 파일에서 annotation-config.

이전 코드보다 훨신 간결하게 프로퍼티나 생성자 부분 없이 깔끔해졌다.

 

 

 

@Autowired 애노테이션으로 인해 코드가 더깔끔해짐 (위-애노테이션 / 아래-프로퍼티&생성자방식)

 

 

@Qualifier 애노테이션을 이용한 의존 객체 선택

 

package member.dao;
public class GuestDao implements Dao {
@Override
public void insert() {
System.out.println("게스트 회원 정보 데이터베이스 저장");
}
@Override
public void select() {
System.out.println("게스트 회원 정보 검색");
}
@Override
public void delete() {
System.out.println("게스트 회원 정보 삭제");
}
@Override
public void update() {
System.out.println("게스트 회원 정보 수정");
}
}

memberDao를 복사해서 GuestDao를 만들어준 뒤 실행하면 dao가 두개라서 에러가 난다.

 

Qualifier를 이용해서 value값을 설정해주고 클래스에서 Qulifier 어노테이션으로 지정해준 후 Main 실행

 

@Autowired 의 필수 여부 지정

 

주석처리 하니 Dao가 없어서 에러가난다 (당연..)

 

없더라도 인스턴스는 생성되도록 한다.

대부분은 꼭 있어야하는 Dao같은 상황에 사용하지만, 존재의 유무를 확인할 때 등등 정리해서 쓰면 좋다.

 

 

 

@Resource 애노테이션을 이용한 자동 의존 주입

 

id를 name으로 써서 구별한다.

그러나 타입으로 구별하는 @autowired를 더 자주사용한다.

타입을 맞추는 것이 더 정확하고 에러가 덜 나기 때문이래나 뭐래나.. 암튼 그렇다!

자동 주입과 명시적 의존 주입 설정이 함께 사용되는 경우 명시적인 의존 주입 설정이 우선한다

 

.

 

 

 

 

[Spring] 의존객체 자동 주입(Automatic Dependency Injection), @Autowired, @Resource, @Inject

| 의존객체 자동 주입(Automatic Dependency Injection) 의존 객체 자동 주입(Automatic Dependency Injection)은 스프링 설정파일에서  혹은  태그로 의존 객체 대상을 명시하지 않아도 스프링 컨테이너가 자..

xzio.tistory.com

 

'spring' 카테고리의 다른 글

[스프링] jdbc  (0) 2021.01.11
[스프링] 파일업로드  (0) 2021.01.08
[스프링] MVC - 컨트롤러 구현  (0) 2021.01.08
[스프링] MVC : 패턴  (0) 2021.01.08
[스프링] 자바 프로젝트를 메이븐 기반의 프로젝트로 변환하기  (0) 2021.01.06
[스프링] 기본 설정  (0) 2021.01.05
[스프링] 설치  (0) 2021.01.05

+ Recent posts