AppConfig에 '구성 정보'를 의미하는 @Configuration 애노테이션을 붙인다.
DI 하는 메서드에 @Bean애노테이션을 붙인다.
2) ApplicationContext에 Bean을 등록
테스트를 위해 작성했던 MemberApp를 열어보자.
기존에는 AppConfig 에서 직접 필요한 객체를 꺼냈었다. 이제 스프링을 쓰자.
스프링은 ApplicationContext 로 시작한다. 이것이 객체(Bean)을 관리해주는 스프링 컨테이너다.
AppConfig.class 를 파라미터로 넘겨서 ApplicationContext를 생성하자.
AppConfig에 있는 설정 정보를 가지고 Bean을 스프링 컨테이너에 넣고 관리해준다.
객체(Bean)의 이름은 각각의 메서드 이름으로 붙여진다. ex) memberService 빈, memberRepository 빈
memberService 객체가 필요할 때 AppConfig에서 꺼내지 않고, 스프링 ApplicationContext에서 꺼낸다.
스프링 컨테이너에 빈으로 등록된 인스턴스가 로그에 뜬다!
3) OrderApp도 스프링으로 바꿔보자.
AppConfig.class 를 파라미터로 넘겨서 ApplicationContext를 생성하자.
ApplicationContext 에서 memberService와 orderService를 꺼낸다.
4) 스프링 컨테이너 (== DI 컨테이너)
ApplicationContext를 스프링 컨테이너라 한다.
기존에는 개발자가 AppConfig 에 객체를 생성하고 직접 DI를 구현했다.
이제 스프링 컨테이너가 @Configuration 애노테이션이 붙은 AppConfig를 설정(구성)정보로 사용한다. 여기서 @Bean이 붙은 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 모두 등록한다. 이렇게 스프링 컨테이너에 등록된 메서드를 스프링 빈이라고 한다.
스프링 빈은 @Bean애노테이션이 붙은 메서드 이름을 스프링 빈의 이름으로 사용한다.
스프링 빈은 applicationContext.getBean() 메서드로 찾을 수 있다.
코드가 더 복잡해진 것 같은데. 스프링 컨테이너를 사용하면 어떤 장점이 있을까 ? 다음 시간에 장점을 배우자.
#include <bits/stdc++.h>
using namespace std;
struct student{
string name;
int kor, eng, math;
};
int n, kor, eng, math;
string st;
vector<student> v;
bool cmp(student &a, student &b){
if(a.kor == b.kor && a.eng == b.eng && a.math == b.math) return a.name < b.name;
else if(a.kor == b.kor && a.eng == b.eng) return a.math > b.math; // 수학 감소하는 순서
else if(a.kor == b.kor) return a.eng < b.eng; // 영어 증가하는 순서
else return a.kor > b.kor; //국어 감소하는 순서
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 0; i < n; i++){
cin >> st >> kor >> eng >> math;
student s = {st, kor, eng, math};
v.push_back(s);
}
sort(v.begin(), v.end(), cmp);
for(auto i : v) cout << i.name << '\n';
return 0;
}
리뷰
비교 함수를 정확히 구현해야 맞을 수 있는 문제였다. 비교 함수를 작성할 때 조건이 구체적인 것 부터 걸러내야 한다. 그래서 '모든 점수가 같으면' 이름이 사전순 증가 하게 출력하라는 조건부터 if문을 시작해야 한다. 문제에서 나오는 조건 대로 작성했다가 처음 풀었을 때 틀렸다.