| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- JavaScript 내장객체
- tdd
- TodayILearned
- framework
- 자바프로그래밍
- 자바스크립트
- TIL
- progressive web app
- 스프링
- 서브쿼리
- maven
- web
- 프레임워크
- CSS
- springaop
- 오라클
- 프로그레시브웹앱
- js
- javascript
- 메이븐
- HTML
- PWA
- sqldeveloper
- 국비지원
- 생활코딩
- sql
- SpringMVC
- Oracle
- mybatis
- javaprogramming
- Today
- Total
1cm
자바 프로그래밍_Day_103_Spring DI 본문

2022. 01. 12

클래스패스에서 가져오는 것을 선호한다.

name 대신에 index를 사용해서 구분도 가능하다.
스프링 3.0부터 지원되는 xml namespace c와 p를 추가시켜줬다. (xmlns:c, p)
<?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:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
c:namespace 활용
ref가 없는 애들 : 리터럴 값을 넘겨줄 때 사용하게 됨
ref가 있는 애들 : 다른 bean을 참조하기 위해 씀

기존 namespace보다 간결하게 작성할 수 있다.
-> 생성자의 인자값을 bean태그의 속성값으로 선언하기 위해서 사용한다.
<bean id="owner" class="com.kh.di.owner.Owner" c:name="홍길동" c:age="20" c:pet-ref="cat"/>
아니면 몇 번째 인자번호인지 넣어서도 사용할 수 있다.
<bean id="owner" class="com.kh.di.owner.Owner" c:_0="홍길동" c:_1="20" c:_2-ref="cat"/>
생성자의 매개값이 하나일 경우 c_="매개값"으로도 표현이 가능하다.
<!--
Pet pet = new Cat("나비")
<bean id="cat" class="com.kh.di.pet.Cat">
<constructor-arg name="name" value="나비"/>
</bean>
-->
<!-- 생성자의 매개값이 하나일 경우 아래와 같이 작성이 가능하다. -->
<bean id="cat" class="com.kh.di.pet.Cat" c:_="초롱이"/>
xmlns:p 적용 : c처럼 일반 리터럴일 경우 ref가 없는 것으로, 다른 bean을 참조할 경우 ref가 붙은 것으로 사용한다.

p는 setter로 주입한다.
<bean id="dog" class="com.kh.di.pet.Dog" p:name="인절미" />
보통 context파일을 연관된 애들끼리 나눠서 관리를 하기 때문에 실습에서도 그렇게 나눠주는 작업을 진행한다.
src > spring에 owner-context.xml >



beans의 디폴트로 사용시 맨 위에 것 사용.

c, p도 같이 추가해줌

이렇게 생성된다.
그리고 root-context.xml에 있는 owner에 대한 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:c="http://www.springframework.org/schema/c"
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">
<!--
기존 방식 :
Owner owner = new Owner("홍길동", 20, new Cat("나비"));
<bean id="owner" class="com.kh.di.owner.Owner">
<constructor-arg name="name" value="홍길동" />
<constructor-arg name="age" value="20" />
<constructor-arg name="pet" ref="dog" />
</bean>
<bean>
* name 대신에 index를 사용해서 구분할 수도 있다.
<constructor-arg index="0" value="홍길동" />
<constructor-arg index="1" value="20" />
<constructor-arg index="2" ref="dog" />
</bean>
<bean id="owner" class="com.kh.di.owner.Owner" c:_0="홍길동" c:_1="20" c:_2-ref="dog"/>
-->
<bean id="mrhong" class="com.kh.di.owner.Owner" c:name="홍길동" c:age="20" c:pet-ref="cat"/>
<bean id="dongdong" class="com.kh.di.owner.Owner" c:name="동동이" c:age="30" c:pet-ref="dog"/>
</beans>


그 다음 pet-context.xml 파일을 만들어준 뒤, beans, c, p를 추가해준다.
그리고 pet-context.xml파일에 root-context.xml에 있던 pet들에 대한 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:c="http://www.springframework.org/schema/c"
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">
<!--
Pet pet = new Cat("나비")
<bean id="cat" class="com.kh.di.pet.Cat">
<constructor-arg name="name" value="나비"/>
</bean>
Pet pet = new Dog();
pet.setName("댕댕이");
<bean id="dog" class="com.kh.di.pet.Dog">
<property name="name" value="댕댕이"/>
</bean>
-->
<!-- 생성자의 매개값이 하나일 경우 아래와 같이 작성이 가능하다. -->
<bean id="cat" class="com.kh.di.pet.Cat" c:_="초롱이"/>
<bean id="dog" class="com.kh.di.pet.Dog" p:name="인절미" />
</beans>
그리고 OwnerTest.java에서 보면 이미 root-context.xml을 포함하고 있으므로 root-context.xml에서 pet과 owner를 import시켜주는 작업을 진행

> root-context.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:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- 다른 설정 파일을 가져오기 위해 사용되는 태그 -->
<import resource="owner-context.xml" />
<import resource="pet-context.xml" />
</beans>
테스트가 실행이 될 때, 설정파일을 만들어서 알아서 애플리케이션 컨텍스트를 만들어 줄 수 있게 해주는 dependency를 pom.xml에 추가시켜줌

추가 후 OwnerTest.java에 @ExtendWith(SpringExtension.class)를 붙여줬다.

context에게 설정 파일을 알려주기 위해 @ContextConfiguration 어노테이션을 추가해준다.


두 어노테이션을 붙여줬는데, mrhong이라는 bean을 getBean을 통해서 어떻게 가져올 것인가?
-> hong이라는 객체를 가져오려고 함

진짜 null인지 테스트 진행

@Autowired, @Qualifier("mrhong")을 추가해줬다.


-> 실제로 프로젝트나 애플리케이션에서는 실행할 때 필요한 빈들을 먼저 context가 만들 것이고, 주입받아서 쓰게 된다. (어노테이션 활용 @ExtendWith, @ContextConfiguration)
xml context에서 읽어갈 설정파일을 java-config로 만들기
-> 이 설정파일은 비즈니스 로직을 포함하거나 로직에 영향을 주지도 않음
-> 애플리케이션 컨텍스트가 읽어가서 빈을 만들 때 활용할 설정 파일이라고 보면 됨

클래스 생성
package com.kh.di.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.kh.di.owner.Owner;
import com.kh.di.pet.Cat;
import com.kh.di.pet.Dog;
// Configuration이 추가 되어야만 해당 자바 클래스가 애플리케이션 컨텍스트의 설정파일이라고 선언한다고 볼 수 있다.
@Configuration
public class RootConfig {
@Bean
// Bean을 넘겨주기 위한 메소드
public Dog dog() {
// 리턴하는 객체를 생성자를 통해서 Bean으로 등록하게 됨
return new Dog("댕댕이");
}
@Bean("kitty")
public Cat cat() {
Cat cat = new Cat();
cat.setName("kitty");
return cat;
}
// Bean에 Id를 별도로 지정해주지 않으면 메소드명으로 Id를 지정한다. (owner)
@Bean
public Owner owner() {
return new Owner("홍길동", 20, null);
}
}
owner, cat, dog에 대한 Bean 들을 만들어 줬다.
이 Bean들을 어떻게 연결 시켜줄 것인가?
1. 메소드 직접 호출하는 방법
-> 메소드를 호출한다고 해도 이미 Bean으로 등록 되어 있기 때문에 application context에서 자동으로 등록된 Bean을 넣어준다.
// Bean에 Id를 별도로 지정해주지 않으면 메소드명으로 Id를 지정한다. (owner)
@Bean
public Owner owner() {
// dog() 메소드는 빈으로 등록되어 있기 때문에 호출 시마다 객체를 생성하는 것이 아닌
// 애플리케이션 컨텍스트에서 등록된 Bean 객체를 리턴한다.
return new Owner("홍길동", 20, dog());
}
-> Test 진행
GenericXml보다 ApplicationContext가 더 상위에 있기 때문에 (다형성), ApplicationContext = GenericXmlApplication이 들어갈 수 있다.
// 애플리케이션 컨텍스트를 통해 객체를 가져오기
@Test
public void contextTest() {
// 스프링의 애플리케이션 컨텍스트를 활용하여 객체 간의 결합을 더욱 느슨하게 만들어준다.
// new GenericXmlApplicationContext(클래스패스 상의 xml 파일의 위치 지정");
ApplicationContext context =
// new GenericXmlApplicationContext("spring/root-context.xml");
// new GenericXmlApplicationContext("classpath:spring/root-context.xml");
// new GenericXmlApplicationContext("file:src/main/resources/spring/root-context.xml");
// new GenericXmlApplicationContext("spring/owner-context.xml", "spring/pet-context.xml");
// 설정 파일로 쓸 자바 파일을 명시해주면 된다.
new AnnotationConfigApplicationContext(RootConfig.class);
설정파일로 쓸 자바파일을 명시만 해줘도 되는 이유?
-> 같은 자바 파일이고, import가 되어있고, class에 Bean이 붙어있는 메소드를 가지고 Bean도 만들어주고 연결도 시켜줌

Application context의 설정을 바꾼 값으로 잘 출력이 되는 것을 확인
두 번째 방법
@Bean("dongdong")
public Owner owner2(@Autowired @Qualifier("kitty") Pet pet) {
return new Owner("동동이", 30, pet);
}
새로운 owner2를 만들어줬다.

그 다음 @ContextConfiguration(classes = {RootConfig.class})의 어노테이션을 만들어줬다.
그리고 context파일을 owner와 pet들로 나눴던 것 처럼 config파일도 Owner,Pet config파일을 만들어준 뒤, RootConfig에 있던 owner, pet에 대한 빈들을 각각 옮겨준다.
> OwnerConfig.java
package com.kh.di.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.kh.di.owner.Owner;
import com.kh.di.pet.Pet;
@Configuration
public class OwnerConfig {
// Bean에 Id를 별도로 지정해주지 않으면 메소드명으로 Id를 지정한다. (owner)
@Bean("mrhong")
public Owner owner() {
// dog() 메소드는 빈으로 등록되어 있기 때문에 호출 시마다 객체를 생성하는 것이 아닌
// 애플리케이션 컨텍스트에서 등록된 Bean 객체를 리턴한다.
return new Owner("홍길동", 25, dog());
}
@Bean("dongdong")
// Autowired는 생략 가능 : 현재 파일은 설정파일인데, 매개값으로 받는 객체가 있으면 application context상에 Pet 타입의 Bean이 있는지 확인
// -> 있으면 주입해준다.
// 만약 Qualifier를 생략해주고 싶다면 @Primary를 달아준다.
public Owner owner2(@Autowired @Qualifier("kitty") Pet pet) {
return new Owner("동동이", 30, pet);
}
}

-> dog()에서 에러 발생 -> OwnerConfig에 dog()라는 메소드가 없어서 발생하는 에러 -> dog라는 bean을 주입해줘야 함
// Bean에 Id를 별도로 지정해주지 않으면 메소드명으로 Id를 지정한다. (owner)
@Bean("mrhong")
public Owner owner(@Autowired @Qualifier("dog") Pet pet) {
// dog() 메소드는 빈으로 등록되어 있기 때문에 호출 시마다 객체를 생성하는 것이 아닌
// 애플리케이션 컨텍스트에서 등록된 Bean 객체를 리턴한다.
return new Owner("홍길동", 25, pet);
}
위처럼 owner에 넣어준다.
만약 mrhong의 빈을 만들 때 애플리케이션 컨텍스트에 Pet타입의 pet이 없는 경우 일단 보류 -> 한바퀴 돌고 다시 보류된 부분을 확인해서 주입된다.
> PetConfig.java
package com.kh.di.config;
import org.springframework.context.annotation.Bean;
import com.kh.di.pet.Cat;
import com.kh.di.pet.Dog;
@Configuration
public class PetConfig {
@Bean
// Bean을 넘겨주기 위한 메소드
public Dog dog() {
// 리턴하는 객체를 생성자를 통해서 Bean으로 등록하게 됨
return new Dog("댕댕이");
}
@Bean("kitty")
// <bean primary="true" />와 같다.
// @Primary
public Cat cat() {
Cat cat = new Cat();
cat.setName("kitty");
return cat;
}
}
- 테스트 실행시킬 때 에러 발생 -> bean을 찾을 수 없다고 나옴
-> xml로 진행 시
1. import
2. application context에 두 개의 config를 읽을수 있게 한다.

> RootConfig 파일에 @Import를 추가시켜주는 방법

> OwnerTest에 @Contextconfiguration에 추가 시켜주는 방법
웬만하면 첫 번째 방법을 쓰는 것을 권장
@어노테이션으로 Spring DI 활용
- 패키지 구조만 만들어 놓기
- 캐릭터 / 무기를 가질 수 있다
- 캐릭터 / 활을 쏠 수 있다.

character class 생성
package com.kh.di.character;
import com.kh.di.character.weapon.Weapon;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Character {
private String name;
private int level;
// 인터페이스
private Weapon weapon;
}

여러 가지의 무기들을 코드 수정없이 사용하기 위해 무기 인터페이스를 만들어줌
package com.kh.di.character.weapon;
public interface Weapon {
// 무기마다 공격 방식이 다르기 때문에 어떻게 공격할 것인지에 대한 설정 - 추상 메소드
public String attack();
}

칼에 대한 클래스 생성하면서 무기 인터페이스 참조할 수 있도록 추가시켜줌
package com.kh.di.character.weapon;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Sword implements Weapon {
// 칼(무기)에대한 이름
private String name;
@Override
public String attack() {
return "검을 휘두른다.";
}
}
그 다음 활(무기) class 만들어줌

package com.kh.di.weapon;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Bow implements Weapon {
// 활에 대한 이름
private String name;
@Override
public String attack() {
return "활을 쏜다. 슉!";
}
}

CharacterTest 만들어줬다.
package com.kh.di.character;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import com.kh.di.weapon.Sword;
class CharacterTest {
@Test
@Disabled
public void test() {
}
@Test
public void create() {
// new Character(캐릭터 이름, 레벨, 무기("무기명"));
Character character = new Character("알렉산더", 1, new Sword("의검"));
assertThat(character).isNotNull();
assertThat(character.getWeapon()).isNotNull();
}
}
실습 전체 코드
> OwnerTest.java
package com.kh.di.owner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.kh.di.config.OwnerConfig;
import com.kh.di.config.PetConfig;
import com.kh.di.config.RootConfig;
import com.kh.di.pet.Cat;
import com.kh.di.pet.Dog;
// JUnit에서 스프링을 사용할 수 있도록 SpringExtension.class를 사용하여 기능을 확장한다.
// 해당 설정이 있어야 @ContextConfiguration()을 통해서 설정 파일을 고, 애플리케이션 컨텍스트를 생성할 수 있다.
@ExtendWith(SpringExtension.class)
//@ContextConfiguration(locations = {"classpath:spring/root-context.xml"})
@ContextConfiguration(classes = {RootConfig.class})
//@ContextConfiguration(classes = {
// OwnerConfig.class,
// PetConfig.class
// })
class OwnerTest {
// 애플리케이션 컨텍스트 상에서 클래스 타입과 일치하는 빈을 자동으로 주입시켜준다.
// 이 때 동일한 클래스 타입에 빈이 여러 개 존재할 경우 @Qualifier("bean ID")를 명시적으로 넣어주어야 한다.
// 직접적으로 @QUalifier를 주지 않고도 애플리케이션 컨텍스트 상에서 겹치는 타입의 빈이 여러 개 있을 때 primary="true"로 기본 빈을 지정할 수 있다.
// -> owner-context.xml에서 확인 가능
@Autowired
@Qualifier("dongdong")
// 가져오려는 객체 : 아무것도 안 넣어주면 null이 들어감 (JVM에서 기본적으로 넣어줌)
private Owner owner;
@Test
@Disabled
public void nothing() {
}
@Test
public void create() {
// 기존에 자바 애플리케이션에서는 다형성과 생성자 주입을 통해 객체간의 결합을 느슨하게 만들어 준다.
Owner owner = new Owner("홍길동", 20, new Cat("나비"));
assertThat(owner).isNotNull();
assertThat(owner.getPet()).isNotNull();
}
// 애플리케이션 컨텍스트를 통해 객체를 가져오기
@Test
public void contextTest() {
// 스프링의 애플리케이션 컨텍스트를 활용하여 객체 간의 결합을 더욱 느슨하게 만들어준다.
// new GenericXmlApplicationContext(클래스패스 상의 xml 파일의 위치 지정");
ApplicationContext context =
// new GenericXmlApplicationContext("spring/root-context.xml");
// new GenericXmlApplicationContext("classpath:spring/root-context.xml");
// new GenericXmlApplicationContext("file:src/main/resources/spring/root-context.xml");
// new GenericXmlApplicationContext("spring/owner-context.xml", "spring/pet-context.xml");
// 설정 파일로 쓸 자바 파일을 명시해주면 된다.
new AnnotationConfigApplicationContext(RootConfig.class);
// object로 가져온 후 형변환
// Owner owner = (Owner) context.getBean("owner");
// 두 번째 매개값에 bean을 가져올 때 변환해서 가져올 타입 명시
// Owner owner = context.getBean("owner", Owner.class);
Owner owner = context.getBean("dongdong", Owner.class);
assertThat(owner).isNotNull();
assertThat(owner.getPet()).isNotNull();
}
@Test
public void autoWiredTest() {
assertThat(owner).isNotNull();
assertThat(owner.getPet()).isNotNull();
assertThat(owner.getPet().bark()).isNotNull().isEqualTo("야옹~");
}
}
> owner-context.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:c="http://www.springframework.org/schema/c"
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">
<!--
기존 방식 :
Owner owner = new Owner("홍길동", 20, new Cat("나비"));
<bean id="owner" class="com.kh.di.owner.Owner">
<constructor-arg name="name" value="홍길동" />
<constructor-arg name="age" value="20" />
<constructor-arg name="pet" ref="dog" />
</bean>
<bean>
* name 대신에 index를 사용해서 구분할 수도 있다.
<constructor-arg index="0" value="홍길동" />
<constructor-arg index="1" value="20" />
<constructor-arg index="2" ref="dog" />
</bean>
<bean id="owner" class="com.kh.di.owner.Owner" c:_0="홍길동" c:_1="20" c:_2-ref="dog"/>
-->
<!-- <bean id="mrhong" primary="true" class="com.kh.di.owner.Owner" c:name="홍길동" c:age="20" c:pet-ref="cat"/> -->
<bean id="mrhong" class="com.kh.di.owner.Owner" c:name="홍길동" c:age="20" c:pet-ref="cat"/>
<bean id="dongdong" class="com.kh.di.owner.Owner" c:name="동동이" c:age="30" c:pet-ref="dog"/>
</beans>
> pet-context.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:c="http://www.springframework.org/schema/c"
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">
<!--
Pet pet = new Cat("나비")
<bean id="cat" class="com.kh.di.pet.Cat">
<constructor-arg name="name" value="나비"/>
</bean>
Pet pet = new Dog();
pet.setName("댕댕이");
<bean id="dog" class="com.kh.di.pet.Dog">
<property name="name" value="댕댕이"/>
</bean>
-->
<!-- 생성자의 매개값이 하나일 경우 아래와 같이 작성이 가능하다. -->
<bean id="cat" class="com.kh.di.pet.Cat" c:_="초롱이"/>
<bean id="dog" class="com.kh.di.pet.Dog" p:name="인절미" />
</beans>
> root-context.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:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- 다른 설정 파일을 가져오기 위해 사용되는 태그 -->
<import resource="owner-context.xml" />
<import resource="pet-context.xml" />
</beans>
> OwnerConfig.java
package com.kh.di.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.kh.di.owner.Owner;
import com.kh.di.pet.Pet;
@Configuration
public class OwnerConfig {
// Bean에 Id를 별도로 지정해주지 않으면 메소드명으로 Id를 지정한다. (owner)
@Bean("mrhong")
public Owner owner(@Autowired @Qualifier("dog") Pet pet) {
// dog() 메소드는 빈으로 등록되어 있기 때문에 호출 시마다 객체를 생성하는 것이 아닌
// 애플리케이션 컨텍스트에서 등록된 Bean 객체를 리턴한다.
return new Owner("홍길동", 25, pet);
}
@Bean("dongdong")
// Autowired는 생략 가능 : 현재 파일은 설정파일인데, 매개값으로 받는 객체가 있으면 application context상에 Pet 타입의 Bean이 있는지 확인
// -> 있으면 주입해준다.
// 만약 Qualifier를 생략해주고 싶다면 @Primary를 달아준다.
public Owner owner2(@Autowired @Qualifier("kitty") Pet pet) {
return new Owner("동동이", 30, pet);
}
}
> PetConfig.java
package com.kh.di.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.kh.di.pet.Cat;
import com.kh.di.pet.Dog;
@Configuration
public class PetConfig {
@Bean
// Bean을 넘겨주기 위한 메소드
public Dog dog() {
// 리턴하는 객체를 생성자를 통해서 Bean으로 등록하게 됨
return new Dog("댕댕이");
}
@Bean("kitty")
// <bean primary="true" />와 같다.
// @Primary
public Cat cat() {
Cat cat = new Cat();
cat.setName("kitty");
return cat;
}
}
> RootConfig.java
package com.kh.di.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Primary;
import com.kh.di.owner.Owner;
import com.kh.di.pet.Cat;
import com.kh.di.pet.Dog;
import com.kh.di.pet.Pet;
// Configuration이 추가 되어야만 해당 자바 클래스가 애플리케이션 컨텍스트의 설정파일이라고 선언한다고 볼 수 있다.
@Configuration
@Import(value = {
OwnerConfig.class,
PetConfig.class
})
// 참고용 : 자바에서 다른 설정 파일을 가져오고 싶을 때(XML) 사용
//@ImportResource(location = {"classpath"})
public class RootConfig {
/*
@Bean
// Bean을 넘겨주기 위한 메소드
public Dog dog() {
// 리턴하는 객체를 생성자를 통해서 Bean으로 등록하게 됨
return new Dog("댕댕이");
}
// Bean에 Id를 별도로 지정해주지 않으면 메소드명으로 Id를 지정한다. (owner)
@Bean("mrhong")
public Owner owner() {
// dog() 메소드는 빈으로 등록되어 있기 때문에 호출 시마다 객체를 생성하는 것이 아닌
// 애플리케이션 컨텍스트에서 등록된 Bean 객체를 리턴한다.
return new Owner("홍길동", 25, dog());
}
*/
}
> Owner.java
package com.kh.di.owner;
import com.kh.di.pet.Cat;
import com.kh.di.pet.Dog;
import com.kh.di.pet.Pet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Owner {
private String name;
private int age;
private Pet pet;
}
> Pet.java
package com.kh.di.pet;
public interface Pet {
// 추상 메소드 생성 (Cat, Dog 공통적으로 들어가는 메소드를 추상화 해줌)
public String bark();
}
> Dog.java
package com.kh.di.pet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dog implements Pet{
private String name;
@Override
public String bark() {
return "멍멍!";
}
}
> Cat.java
package com.kh.di.pet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Cat implements Pet{
private String name;
@Override
public String bark() {
return "야옹~";
}
}
캐릭터 + 무기에 대한 코드는 위에 작성한 것이 전부
'국비지원_Java > Java Programming_2' 카테고리의 다른 글
| 자바 프로그래밍_Day_105_Spring AOP (0) | 2022.02.02 |
|---|---|
| 자바 프로그래밍_Day_104_Spring DI / AOP (0) | 2022.01.31 |
| 자바 프로그래밍_Day_102_인터페이스 구현 평가 (0) | 2022.01.21 |
| 자바 프로그래밍_Day_101_스프링 개요 (0) | 2022.01.21 |
| 자바 프로그래밍_Day_100_Framework : MyBatis 정리 / log4j (0) | 2022.01.19 |