개발이 좋아서/Spring이 좋아서
프록시 - 프록시 패턴(접근 제어)
public interface Subject { String operation();}@Slf4jpublic class RealSubject implements Subject { @Override public String operation() { log.info("실제 객체 호출"); sleep(1000); return "data"; } private void sleep(int millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { e.printStackTrace(); } }}public..
디자인 패턴 - 전략 패턴(템플릿 콜백 패턴)
@Testvoid templateMethodV0() { logic1(); logic2();}private void logic1() { long startTime = System.currentTimeMillis(); //비즈니스 로직 실행 log.info("비즈니스 로직1 실행"); //비즈니스 로직 종료 long endTime = System.currentTimeMillis(); long resultTime = endTime - startTime; log.info("resultTime={}", resultTime);}private void logic2() { long startTime = System.currentTimeMillis(); //비즈..
디자인 패턴 - 템플릿 메서드 패턴
@Testvoid templateMethodV0() { logic1(); logic2();}private void logic1() { long startTime = System.currentTimeMillis(); //비즈니스 로직 실행 log.info("비즈니스 로직1 실행"); //비즈니스 로직 종료 long endTime = System.currentTimeMillis(); long resultTime = endTime - startTime; log.info("resultTime={}", resultTime);}private void logic2() { long startTime = System.currentTimeMillis(); //비즈..
ThreadLocal - 동시성 문제
Field@Slf4jpublic class FieldService { private String nameStore; public String logic(String name) { log.info("저장 name={} -> nameStore={}", name, nameStore); nameStore = name; sleep(1000); log.info("조회 nameStore={}", nameStore); return nameStore; } private void sleep(int millis) { try { Thread.sleep(millis); } catch (Interrup..
빈 스코프 - 웹 스코프(Provider/프록시)
스코프와 Provider@Component@Scope(value = "request")public class MyLogger { private String uuid; private String requestURL; public void setRequestURL(String requestURL) { this.requestURL = requestURL; } public void log(String message) { System.out.println("[" + uuid + "]" + "[" + requestURL + "] " + message); } @PostConstruct public void init() { String u..
빈 스코프 - 프로토타입 스코프
프로토타입 스코프 - 싱글톤 빈과 함께 사용 시 Provider로 문제 해결public class SingletonWithPrototypeTest1 { @Test void prototypeFind() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class); PrototypeBean prototypeBean1 = ac.getBean(PrototypeBean.class); prototypeBean1.addCount(); assertThat(prototypeBean1.getCount()).isEqualTo(1); ..
빈 생명주기 콜백
크게 3가지 방법이 있다.인터페이스(InitializingBean, DisposableBean)설정 정보에 초기화 메서드, 종료 메서드 지정@PostConstruct, @PreDestroy 애노테이션 지원 인터페이스 InitializingBean, DisposableBeanpublic class NetworkClient implements InitializingBean, DisposableBean { private String url; public NetworkClient() { System.out.println("생성자 호출, url" + url); } public void setUrl(String url) { this.url = url; } /..
의존관계 자동 주입
생성자 주입@Componentpublic class OrderServiceImpl implements OrderService { private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }}생성자 호출시점에 딱 1번만 호출..
컴포넌트 스캔
@Configuration@ComponentScan( excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class))public class AutoAppConfig {}@Componentpublic class MemberServiceImpl implements MemberService { private final MemberRepository memberRepository; @Autowired public MemberServiceImpl(MemberRepository memberRepository) { this.memberRepository = me..
@Configuration - 싱글톤 보장
@Configurationpublic class AppConfig { @Bean public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } @Bean public MemberRepository memberRepository() { return new MemoryMemberRepository(); } @Bean public OrderService orderService() { return new OrderServiceImpl(memberRepository(), discountPolicy()); } @Bean ..