Repository, Service, Test, springBean, component scan
๐ Summary
- โ๏ธ Optional
if there is possibility to be null,
Optional
and useifPresent
- โ๏ธ Test code:
- given, when, then
Asssertions.assertThat()
- for exceptions, use
Assertions.assertThrows()
@AfterEach()
to clear data@BeforeEach()
to inject repository in service โก๏ธ dependency injection- โ๏ธ Component scan, spring bean
@Component
์ ๋ถ์ด๋ฉดspring bean
์ผ๋ก ์๋ ๋ฑ๋ก๋จspring bean
์ผ๋ก ๋ฑ๋ก๋๋ฉด:spring container
๊ฐ dependency inject@Component
๋ ํ๋๋ง ๋ง๋ค์ดspring container
๊ฐ ๊ด๋ฆฌ โก๏ธ singleton(ํ๋๋ง uniqueํ๊ฒ ๋ง๋ ๋ค)@Autowired
๋ฅผ ์จ์spring bean
์ ์๋์ผ๋ก inject dependency, ์ด์ ์๋น์ค๋ repository๋ฅผ ์ธ ์ ์๊ณ controller๋ ์๋น์ค๋ฅผ ๊ฐ์ ธ๋ค ์ธ ์ ์์
โ Repository
Member Repository
is interfaceMemory Member Repository
implementsMember Repository
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
29
30
31
32
33
34
//interface MemberRepository
public interface MemberRepository {
Member save(Member member);
Optional<Member> findById(Long id);
Optional<Member> findByName(String name);
List<Member> findAll();
}
//MemoryMemberRepository
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
@Override
public Member save(Member member) {
}
@Override
public Optional<Member> findById(Long id) {
//optional: to handle if return value is null
}
@Override
public Optional<Member> findByName(String name) {
}
@Override
public List<Member> findAll() {
}
public void clearStore(){ //to clear repository after test
store.clear();
}
}
โ Repository Test
- โญ๏ธ After each
- ํ ์คํธ ์คํ ํ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฆฌ(clear)ํ๋ ์ฝ๋
MemoryMemberRepositoryTest
test code์์๋ 3๊ฐ์ ํ ์คํธ๊ฐ ๋ค์ด์์- ์ด 3๊ฐ์ ํ ์คํธ๋ ์์๊ฐ ๋ณด์ฅ์ด ์ ๋จ
๋ฐ๋ผ์ ํ ๊ฐ์ ํ ์คํธ๊ฐ ๋๋๋ฉด
repository
๋ฅผ ์ด๊ธฐํํด ์ฃผ์ด์ผ ํจ โก๏ธafterEach()
- โญ๏ธ
Assertions.assertThat()
์ ์ฌ์ฉํด ๊ฒฐ๊ณผ ๋น๊ต
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class MemoryMemberRepositoryTest {
MemoryMemberRepository respository = new MemoryMemberRepository();
@AfterEach
public void afterEach(){
respository.clearStore();
//ํ
์คํธ๋ ์์ ๋ณด์ฅ์ด ์ ๋จ
//ํ
์คํธ ํ๋ ๋๋ ๋๋ง๋ค ์ด๊ธฐํ
}
@Test
public void save(){
Member member = new Member();
member.setName("spring");
respository.save(member);
Member result = respository.findById(member.getId()).get();
assertThat(member).isEqualTo(result);
}
@Test
public void findByName(){
Member member1 = new Member();
member1.setName("spring1");
respository.save(member1);
Member member2 = new Member();
member2.setName("spring2");
respository.save(member2);
Member result = respository.findByName("spring1").get();
assertThat(result).isEqualTo(member1);
}
@Test
public void findAll(){
Member member1 = new Member();
member1.setName("spring1");
respository.save(member1);
Member member2 = new Member();
member2.setName("spring2");
respository.save(member2);
List<Member> result = respository.findAll();
assertThat(result.size()).isEqualTo(2);
}
}
โ Member Service
- โญ๏ธ Optional
Optional
:null
์ด ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ฒ์ ๊ฐ์ผ๋ค- ๋ฉค๋ฒ๋ฅผ
name
์ผ๋ก ์ฐพ์ ๋, ์์ ์๋ ์์ผ๋(null
)Optional
๋ก ๊ฐ์ผ๋ค
- ๋ฉค๋ฒ๋ฅผ
Optional
์ ์ฌ์ฉํ๋ฉดisPresent
๋ฅผ ์ธ ์ ์์- ๊ทธ๋ฌ๋ฉด
null
์ผ ๋ ~๊ฒ ํ๋ผ๊ณ ์ฝ๊ฒ ๋์ง ์ ์๋ค - ๐๐ป ๊ธฐ์กด์๋ ๋ฉค๋ฒ๋ฅผ ์ฐพ์์
if (member == null)
์ ํ์ด์ผ ํจ - ๐๐ป
Optional
์ ์ฌ์ฉํ๋ฉดisPresent
๋ก ์ฝ๊ฒnull
์์ธ์ฒ๋ฆฌ ๊ฐ๋ฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MemberService{
//repository and constructor
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
//Use of Optional & ifPresent
private void validateDuplicateMember(Member member){
Optional<Member> findMember = memberRepository.findByName(member.getName()); //์์ ์๋ ์์ผ๋ optional๋ก ๊ฐ์ผ๋ค
findMember.ifPresent(m -> {
throw new IllegalStateException("member already exsists");
});
//same code but better!
memberRepository.findByName(member.getName())
.ifPresent(m-> { //optional๋ก ๊ฐ์ธ๋ฉด โก๏ธ ifPresent๋ก ์๋์ง ํ์ธํ๊ณ throw๊ฐ๋ฅ
throw new IllegalStateException("member already exists");
});
}
}
๐ก DI
์๋น์ค ๊ฐ์ฒด๊ฐ ์์ ์ด ์์กดํ๋ ๋ฆฌํฌ์งํ ๋ฆฌ ๊ฐ์ฒด์ ๊ตฌํ์ฒด๋ฅผ ์ง์ ์์ฑํ์ง ์๊ณ , ์ธ๋ถ(์ค์ ๋ฑ)์์ ์ ๋ฌ๋ฐ์ ์ฌ์ฉํ๋ ์ค๊ณ ๋ฐฉ์
โ Member Serice Test
use
given, when, then
- โญ๏ธ DI, Before Each
memberService Test
๊ฐ ์์ฑ๋ ๋memberService
์ ํจ๊ปMemoryMemberRepository
๋ ์์ฑ๋๊ฒ ํ๋ค- use
@BeforeEach
- ๊ทธ๋ฆฌ๊ณ
memberService
์MemoryMemberRepository
์ฃผ์ - โก๏ธ Dependency Injection
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository repository;
@BeforeEach
public void beforeEach(){
repository = new MemoryMemberRepository();
memberService = new MemberService(repository); //โญ๏ธ DI
}
@AfterEach
public void afterEach(){
repository.clearStore();
}
@Test
void signUp() { // ์ ์ ํ๋ฆ
//given
Member member = new Member();
member.setName("spring");
//when
Long saveId = memberService.signUp(member);
//then
Member findMember = memberService.findOne(saveId).get();
assertThat(findMember.getName()).isEqualTo(member.getName());
}
@Test
void signUpDuplicate() { //ํ์๊ฐ์
ํ๋๋ฐ ์ด๋ฆ ์ค๋ณต๋๋ ๊ฒฝ์ฐ
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring"); //same name trying to signUp
//when
memberService.signUp(member1);
//then
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.signUp(member2));
assertThat(e.getMessage()).isEqualTo("member already exists");
- โ๏ธ ํ์๊ฐ์
ํ๋๋ฐ ์ด๋ฆ ์ค๋ณต๋๋ ๊ฒฝ์ฐ
signUpDuplicate()
assertThrows(IllegalStateException.class, () -> memberService.signUp(member2))
- ์์ธ์ฒ๋ฆฌ ํฐ์ง๋ฉด,
IllegalStateException.class
- ์ด๋ฆ์ด ๋ค๋ฅด๋ฉด ํ์๊ฐ์ ๊ฐ๋ฅํ๋๋ก
- ๊ทธ๋ฆฌ๊ณ ๋ฐํํ๋ ์์ธ์ฒ๋ฆฌ ๋ฉ์ธ์ง
assertThat
์ฌ์ฉํด์ ๋น๊ตํ๊ธฐ
๐ก Spring Bean and DI with annotation
@Bean
๋ฑ๋กํ๋ ๋ฐฉ๋ฒ- 1๏ธโฃ component scan with
@Autowired
- 2๏ธโฃ manual bean configuration with
@Configuration
1๏ธโฃ Spring bean
with component scan
@Component
๊ฐ ์์ผ๋ฉด ์๋์ผ๋กSpring bean
์ผ๋ก ๋ฑ๋ก๋๋ค.@Controller
,@Service
,@Repository
์ ๋ชจ๋@Component
์ ์ผ์ข ์ด๋ค@Controller
,@Service
,@Repository
๋ผ๋annotation
์ ๋ถ์ฌ๋๋ฉด, ์์ฑ ์spring container
๊ฐ ์ด๋ฅผ ์๊ณ ๊ด๋ฆฌํ๋ค- ๐๐ป
annotation
์ ๋ถ์ฌ๋์ผ๋ฉด ์๋์ผ๋กspring bean
์ ๋ฑ๋ก๋๋ค spring bean
์ ๋ฑ๋ก๋๋ค๋ ์๋ฏธ:spring container
๊ฐ ํ๋๋ง ๋ง๋ค์ด ๊ด๋ฆฌํ๋ค
DI and Autowired
@Controller
is dependent on@Service
for accessing data@Service
is dependent on@Repository
for accessing data- using
@Autowired
, can injectspring bean
dependencies - โก๏ธ dependency injection
@Autowired
์ ์์ผ๋ก์จ controller๋ service๋ฅผ ์ธ ์ ์๊ฒ ๋๊ณ , service๋ repository๋ฅผ ์ธ ์ ์๊ฒ ๋๋ ๊ฒ
๐๐ป Spring Bean์ผ๋ก ๋ฑ๋กํ๋ฉด ์ฅ์
@Component
๋ฅผ ๋ถ์ฌ๋์ผ๋ฉด ๊ฐ controller, service, repository๋ ํ๋๋ง ๋ง๋ค์ดspring container
๊ฐ ๊ณต์ , ๊ด๋ฆฌํ๋ค โก๏ธ singleton- ์๋ฅผ ๋ค์ด
member controller
,order controller
์์ ๋ชจ๋member service
๋ฅผ ํธ์ถํ๋๋ผ๋member service
๋ ํ๋๋ง ๋ง๋ ๋ค spring container
์์ ํด๋นspring bean
์ ์ฐพ์ ์ฃผ์ ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) { //dependency injection by constructor
this.memberService = memberService;
}
}
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) { //dependency injection
this.memberRepository = memberRepository;
}
}
๐ก Manual spring bean injection
2๏ธโฃ Manually configure
spring bean
- annotation์ ์ฐ์ง ์๊ณ ๋ณ๋ ํ์ผ๋ก
spring bean
์ ๊ด๋ฆฌํ๋ค @Configuration
ํ๊ณ config ํ์ผ ์์ฑ@Bean
ํ๊ณ service, repository๋ฅผ ๋ชจ๋spring bean
์ ๋ฑ๋กํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
}
- ํ์ง๋ง
@Controller
๋ annotation์ผ๋ก ๋ฌด์กฐ๊ฑด ๋ฃ์ด์ผ ํ๋ค
โ
โ
โ
โ
โ
This post is licensed under CC BY 4.0 by the author.