객체로 관리할 요소
의존성을 주입해야되는
지정한 패키지 범위를 기본 스캔 대상 스캔 👉 객체 생성
@Component@Service@Controller@RestController@ControllerAdviceRestControllerAdvice@Aspect@Configuration@Repository : DAO에 주로 정의클래스명만 빈의 이름으로 고려
해결방안 @Repository("memberDao2")
수동 등록 빈이 우선
컴포넌트 스캔 내부에는 excludeFilters이 정의 되어있다. 자동스캔범위에 있는 객체를 배제
ManualBean
@Target(ElementType.TYPE) //클래스명, 인터페이스명 위에
@Retention(RetentionPolicy.RUNTIME)
public @interface ManualBean {
}
AppCtx
1. 애노테이션 FilterType.ANNOTATION
2. 클래스 FilterType.ASSIGNABLE_TYPE
3. 정규표현식 FilterType.REGEX
4. aspectJ FilterType.ASPECTJ : 의존성을 추가해야함.
@Configuration
@ComponentScan(basePackages="member", excludeFilters=@ComponentScan.Filter(type=FilterType.ANNOTATION, classes = ManualBean.class))
@ComponentScan(basePackages = "member", excludeFilters = @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, classes = {MemberDao.class, JoinValidator.class}))
@ComponentScan(basePackages = "member", excludeFilters = @ComponentScan.Filter(type= FilterType.REGEX, pattern = "member\\.*Dao"))
@ComponentScan(basePackages = "member", excludeFilters = @ComponentScan.Filter(type= FilterType.ASPECTJ, pattern = "member..*Dao"))
public class AppCtx{ }
MemberDao
MemberDao클래스는 @ManualBean이기 때문에 자동스캔 범위에서 배제된다.
@ManualBean
@Repository
public class MemberDao { // memberDao - 빈 이름
private static Map<String, Member> members = new HashMap<>();
public void register(Member member) {
members.put(member.getEmail(), member);
}
public Member get(String email) {
return members.get(email);
}
public List<Member> getList() {
List<Member> data = new ArrayList<>(members.values());
return data;
}
}
의존성
implementation 'org.aspectj:aspectjweaver:1.9.22.1'
빈 객체의 생성, 의존 주입, 초기화
빈 객체의 소멸
객체 생성 -> 의존 설정 -> 초기화 -> 소멸
ctx.close() - 객체 소멸) : 소멸전에 처리할 작업을 정의하면 실행되는 단계스프링 컨테이너 생성시 진행 되는 부분(객체 생성 👉 의존 설정 👉 초기화)
본인이 만든 클래스만 적용이 가능하다
afterPropertiesSet 메서드 : 초기화 단계시에 실행 된다. (객체가 완전히 조립되고 생성 된 후에 처리할 작업을 정의)destory 메서드 : 컨터이너에 있는 객체가 소멸되기 전에 실행 (주로 객체 소멸전에 할 적업 예) 자원해체 등...)출력결과
afterPropertiesSet()
글쓰기
DisposableBean()
BoardService@Service public class BoardService implements InitializingBean, DisposableBean { @Override public void destroy() throws Exception { System.out.println("DisposableBean()"); } public void write(){ System.out.println("글쓰기"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet()"); } }Test
public class Ex02 { @Test void test1(){ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx.class); //afterPropertiesSet()은이때 실행됨 BoardService service = ctx.getBean(BoardService.class); service.write(); ctx.close(); //destroy()은 이때 실행된다. } }
initalizingBean : afterPropertiesSet 메서드와 동일 시점에 호출
DisposableBean : destroy 메서드와 동일 시점에 호출
@Scope : 클래스명, 메스드명 위에 정의 가능
@Scope("singleton") : 정의하지 않아도 기본은 싱글톤 패턴으로 관리@Scope("prototype") : 매번 조회시마다 새로운 객체를 생성 @Scope("prototype") //매번 새로운 객체를 생성
@Bean(initMethod = "init", destroyMethod = "destroy") //외부에서 가져왔다고 가정했기 때문에 수동으로 지정해야한다.
public BoardService2 boardService2(){
return new BoardService2();
}
@Test
void test1(){
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx.class);
BoardService2 s1 = ctx.getBean(BoardService2.class);
BoardService2 s2 = ctx.getBean(BoardService2.class);
System.out.println(s1 == s2); //false
ctx.close();
}