묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
윈도우에서 java은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. 오류 나시는 분들 참고하시면 좋을것 같습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요.'java'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. 라는 오류는아래 블로그 참고해서 해주시면 됩니다!!2번 단계부터 진행하시면 되요~!!https://m.blog.naver.com/under0tree/222343927513다만, 경로 같은 경우는 intellij에서 File -> Project Structure -> SDKs 에서 JDK home path 에서 확인하시면 될 것 같습니다!!저는 D 드라이브에 설치해놔서 따로 설정해줬습니다!!
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
build.gradle로 프로젝트를 open 해야 하는 이유가 뭘까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]그냥 프로젝트 폴더를 선택해서 열어도 build.gradle 파일을 읽는 것 같은데, 꼭 build.gralde 파일을 선택해서 열어야 하는 이유가 있나요?
-
해결됨스프링 핵심 원리 - 기본편
강의 프로토타입 질문입니다
public class SingletonTest { @Test void singletonBeanFind() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class); SingletonBean singletonBean1 = ac.getBean(SingletonBean.class); SingletonBean singletonBean2 = ac.getBean(SingletonBean.class); System.out.println("singletonBean1 = " + singletonBean1); System.out.println("singletonBean2 = " + singletonBean2); Assertions.assertThat(singletonBean1).isSameAs(singletonBean2); ac.close(); } @Scope("singleton") static class SingletonBean { @PostConstruct public void init() { System.out.println("SingletonBean.init"); } @PreDestroy public void destroy() { System.out.println("SingletonBean.destroy"); } } } 영한님이 AnnotationConfigApplicationContext(SingletonBean.class); 여기에 SingletonBean.class를 넣으면 componentscan이 된다고하셨는데 AnnotationConfigApplicationContext는 @Component 혹은 @Bean으로 등록이 되어있는걸 스프링컨테이너로 만들어서 라이프사이클을 관리한다는건데 여기서는 자동으로 빈이나 수동으로 빈을 등록하는게 없는데 어떻게 컴포넌트 스캔으로 관리가되는거죠? 두번째, 컴포넌트스캔이 @SpringBootApplication에 내장되어있어서 자동으로 진행되는건알고있는데 @Test에도 영향을미치나요? 저는 test는 별도로 component를 해줘야하는지 생각했는데 아닌거같아서요
-
미해결스프링 핵심 원리 - 기본편
request scope 관련 질문
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 내용]request scope 관련해서 실행 과정에서 궁금한게 생겨서 질문드립니다. 제가 이해한 과정이 맞을까요?1. 먼저 CoreApplication을 실행시키면 스프링 컨테이너가 생성이 되고, MyLogger라는 빈을 스프링 컨테이너에 등록시킨다MyLogger라는 빈은 scope이 request 이기때문에http 요청이 오기전까지, 빈 인스턴스를 생성하지 않아서 @PostConstruct가 붙은 초기화 메서드 init()이 실행되지 않는다따라서 uuid를 생성해서 저장하지 못 하기 때문에 "Scope 'request' is not active ... " 와 같은 오류가 발생한다위 과정이 맞다면, 고객의 요청이 오기전까지 Mylogger 빈 인스턴스가 생성되지 않은 상태일텐데 provider가 어떻게 빈을 찾아서 가져오고 @PostContsruct가 실행되는지 궁금합니다. 또한 myLogger.setRequestURL() 메서드가 어느 시점에 실행되는지 궁금합니다.. (빈 생성 전인지 후 인지)그리고 "빈 등록" 과 "빈 생성"은 다른 개념인건가요? 조금 혼동되네요
-
해결됨스프링 핵심 원리 - 기본편
CoreApplication 실행 오류
CoreApplication 실행시 다음과 같은 오류가 발생합니다.
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
sendError부분과 setStatus이 차이가 아직 잘이해가 되지않습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]@Slf4j public class MyHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try{ if(ex instanceof IllegalArgumentException){ log.info("IllegalArgumentException resolver to 400"); response.sendError(HttpServletResponse.SC_BAD_REQUEST,ex.getMessage()); ModelAndView mv=new ModelAndView("test"); System.out.println(mv.getViewName()); mv.addObject("message","안녕하세요"); return mv; } }catch (IOException e){ log.error("reslover ex",e); } return null; } }해당 부분에 대해서 궁금한점이 생겨 질문드립니다.sendError같은경우에는 setStatus와는 다르게 제가 이해하기로는 ModelAndView가 있더라도ModelAndView mv=new ModelAndView("test");1.톰캣(WAS)에 에러가 발생했다는것을 알려주고 또한 톰캣은 해당에러를보고 BasicErrorController로 설정한 뷰를 보여주기떄문에 제가설정한 "test"뷰는 무시되고 retrun되는게 맞나요?2.그리고 또궁금한게 해당 부분이 만약에 맞다고 하면 mv.addObject("message","안녕하세요");제가 만든 "test"라는 ModelAndView객체에 모델 데이터를 담았기떄문에 BasicErrorController설정된 뷰화면에 모델데이터가 넘어가지않아야 정상으로 생각이 되는데 BasicErrorController의 뷰에도 해당 모델데이터가 넘어가는데 이유가 뭔지 궁금합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
컨트롤러 return구문 {}표현식
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요. 커뮤니티 글을 읽어도 답이 없길래 질문드려요. 컨트롤러에서 return할때 소위 말하는 el표현식을 사용해서 {} 이런 기호로 변수를 사용하던데,1.정확히 pathvariable이 있을때만 가능한 문법인건가요?2.매핑url에서는 {test111}로 받더라도@Pathvariable로 변수명을 test222로 바꿀수 있는데, 이 경우에는 return 의 표현식에 test111이 먹히는지 test222가 먹히는지 궁금합니다.. 감삼다
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
typemismatch
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. @PostMapping("/add") public String addItemV4(@ModelAttribute Item item, BindingResult bindingResult , RedirectAttributes redirectAttributes, Model model) { //파라미터 순서 중요 /* ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "itemName", "required");*/ //검증로직 if (bindingResult.hasErrors()) { log.info("errors={}", bindingResult); return "validation/v2/addForm"; } log.info("objectName={}", bindingResult.getObjectName()); log.info("target={}", bindingResult.getTarget()); if (!StringUtils.hasText(item.getItemName())) { /* errors.put("itemName", "상품이름값은 필수입니다.");*//* /* bindingResult.addError(new FieldError("item", "itemName",item.getItemName(),false,new String[]{"required.item.itemName"},null, "상품이름은 필수입니다")); */ bindingResult.rejectValue("item", "required"); } if (item.getPrice() == null || item.getPrice() > 1000000 || item.getPrice() < 1000) { /* errors.put("price", "가격은 1000부터 100000까지만 입력하세요");*/ /* bindingResult.addError(new FieldError("item", "price",item.getPrice(),false,new String[]{"range.item.price"},new Object[]{100,1000000}, "가격은 1000부터 100000까지만 입력하세요")); */ bindingResult.rejectValue("price", "range", new Object[]{1000, 10000000}, null); } if (item.getQuantity() == null || item.getQuantity() >= 9999) { /* errors.put("quantity", "수량은 9999이하만 입력가능합니다");*/ /* bindingResult.addError(new FieldError("item", "quantity",item.getQuantity(),false,new String[]{"max.item.quantity"},new Object[]{9999}, "상품이름은 필수입니다")); */ bindingResult.rejectValue("quantity", "max", new Object[]{9999}, null); } //특정 필드가 아닌 복합 필드 값 검증 if (item.getPrice() != null && item.getQuantity() != null) { int resultPrice = item.getPrice() * item.getQuantity(); if (resultPrice < 10000) { /*errors.put("globalErrors", "수량과 값의 합이 10000이상 이어야합니다. 현재 값은 = " + resultPrice);*/ /* bindingResult.addError(new ObjectError("item",new String[]{"totalPriceMin"},null, "수량과 값의 합이 10000이상 이어야합니다. 현재 값은 = " + resultPrice)); */ bindingResult.reject("totalPriceMin", new Object[]{10000, resultPrice}, null); } }#required.item.itemName=상품 이름은 필수입니다. #range.item.price=가격은 {0} ~ {1} 까지 허용합니다. #max.item.quantity=수량은 최대 {0} 까지 허용합니다. #totalPriceMin=가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1} #==ObjectError== #Level1 totalPriceMin.item=상품의 가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1} #Level2 - 생략 totalPriceMin=전체 가격은 {0}원 이상이어야 합니다. 현재 값 = {1} #==FieldError== #Level1 required.item.itemName=상품 이름은 필수입니다. range.item.price=가격은 {0} ~ {1} 까지 허용합니다. max.item.quantity=수량은 최대 {0} 까지 허용합니다. #Level2 - 생략 #Level3 required.java.lang.String = 필수 문자입니다. required.java.lang.Integer = 필수 숫자입니다. min.java.lang.String = {0} 이상의 문자를 입력해주세요. min.java.lang.Integer = {0} 이상의 숫자를 입력해주세요. range.java.lang.String = {0} ~ {1} 까지의 문자를 입력해주세요. range.java.lang.Integer = {0} ~ {1} 까지의 숫자를 입력해주세요. max.java.lang.String = {0} 까지의 문자를 허용합니다. max.java.lang.Integer = {0} 까지의 숫자를 허용합니다. #Level4 required = 필수 값 입니다. min= {0} 이상이어야 합니다. range= {0} ~ {1} 범위를 허용합니다. max= {0} 까지 허용합니다. typeMismatch.java.lang.Integer=숫자를 입력해주세요. typeMismatch=타입 오류입니다.이렇게 따라했는데이런식으로 가격에 오류코드가 안뜨고 화이트라벨오류가 뜹니다 뭐가 문제인가요??타입미스매치를 에러프로퍼티에 명시해놨는데도 안됩니다ㅠ
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
HandlerExceptionResolver부분에 대해서 질문이있습니다.
[질문 내용]HandlerExceptionResolver시작 17:23초 경 @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try{ if(ex instanceof IllegalArgumentException){ log.info("IllegalArgumentException resolver to 400"); response.sendError(HttpServletResponse.SC_BAD_REQUEST,ex.getMessage()); return new ModelAndView("test"); } }catch (IOException e){ log.error("reslover ex",e); } return null;해당 부분에서 IllegalArgumentException발생되면ModelAndView를 동작시킨다고 하셨는데 response.sendError인해서 400에러가 was까지 전달된후 다시 was는 해당 Error를 읽고 다시 BasicErrorController로 설정된 값이 return 되기때문에 우리가 ModelAndView부분은 sendError로 인해서 반환이 못되는 상태가 아닌가요??제가 잘못 이해했나해서 질문드립니다!
-
해결됨스프링 핵심 원리 - 기본편
강의. 조회된빈이 모두필요할떄 List,map 제목입니다
public class AllBeanTest { @Test void finaAllBean() { ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class); DiscountService discountService = ac.getBean(DiscountService.class); Member member = new Member(1L, "userA", Grade.VIP); int discountPrice = discountService.discount(member, 1000, "fixDiscountPolicy"); assertThat(discountService).isInstanceOf(DiscountService.class); assertThat(discountPrice).isEqualTo(1000); int rateDiscountPrice = discountService.discount(member, 20000, "rateDiscountPolicy"); assertThat(rateDiscountPrice).isEqualTo(2000); } static class DiscountService { private final Map<String, DiscountPolicy> policyMap; private final List<DiscountPolicy> policies; @Autowired // 생략가능 생성자가 하나이기 때문에!!! public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policies) { this.policyMap = policyMap; this.policies = policies; System.out.println("policyMap = " + policyMap); System.out.println("policies = " + policies); } public int discount(Member member, int price, String discountCode) { DiscountPolicy discountPolicy = policyMap.get(discountCode); return discountPolicy.discount(member, price); } } } 첫번째 질문, AnnotationConfigApplicationContext을 해주게되면 스프링컨테이너로 등록을하고 ac를 통해 빈으로 등록된 AutoAppconfig.class와 DiscountService.class에 접근이 가능하다고 알고있습니다.밑에보면 ac로 DiscountService.class에만 접근하고있어서 AutoAppconfig.class를 빼주었더니 밑에있는 discountprice에 discout에서 오류가 발생합니다. 이유가 무엇일까요? 두번째 질문, 밑에 DiscountService에 강의에서 생성자를 선언해주었습니다. 지금보면 어디에서 호출이되었는지와 어떻게 값을 넣어주었는지 궁금합니다. 제생각에는 AnntationConfigApplicationContext를 할때API문서를 보니 refresh()의 finishBeanFactoryInitialization(beanFactory); 에서 AutoAppConfig.class, DiscountService.class 에 대한 값을 이미 생성되었다고 판단되었는데 이게맞을까요? 이게맞다면 1번질문이 결국 2번질문과 연관되어있을거같습니다 세번째 질문, map에 대해 공부를해봤는데 map<String, DiscountPolicy> 에서 만약 AutoAppconfig 가 들어가있다면 this.policyMap에는 AutoAppconfig가 들어가있는 상태이고 AutoAppconfig를 들여다보니 ComponentScan이 있어서 Component로 등록되어있는 RateDiscountPolicy, FixDiscountPolicy에 매개변수로 들어온 discountCode로 접근이 가능하다가 맞을꺼같은데 제가 이해한게맞을까요?
-
미해결실전! 스프링 데이터 JPA
스프링부트 3.2부터 빌드 설정
강의 자료에 스프링 부트 3.2부터는 빌드시 Intellij가 아닌 Gradle을 선택해야 한다고 나와있는데 이 부분 맞나요?
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
예외 추상화 적용시 예외를 service단에서 처리하지 않을경우
안녕하세요 강의 내용 중 문제에 대한 제 생각을 확인차 질문드립니다. JDBC 기술에 종속적인 예외를 spring기술에 종속적인 예외로 바꿔주어 우리가 모든 데이터접근 기술의 예외코드를 알필요없이 문제를 처리할 수 있음을 알겠습니다. 이때 spring 이 제공하는 모든 예외는 RuntimeException이기 때문에 따로 service단에서 try catch로 잡지 않을 경우 생략된 throw로 controller -> servlet container로 자동으로 던져지는게 맞을까요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
AJAX통신
안녕하세요, 김영한 강사님!ajax 통신 관련 강의도 들어야 한다고 생각하는데요!혹시 강사님 강의중에 프론트단과 데이터 통신을 하는 부분의 강의나 ajax 관련강의가 있을까요?ajax 를 몰라서요!강의 목차를 여러개의 강의를 들어가봐서 확인을 해봤더니 ajax 와 관련된 강의를 찾지 못해서요 😃있다면 어느 강의인지 말씀해주시면 감사하겠습니닿ㅎ 백엔드 부분도 ajax 알아야하는것 맞죠?!
-
미해결스프링 핵심 원리 - 기본편
빌드하면 나오는 화면 질문
평소 보던 결과랑 다르게 나오는데 저에게 무슨일이 생긴걸까요? 강의랑 같은 결과화면을 얻고싶습니다!이 부분이 강의와 다르게 나타나는 이유가 무엇일까요?
-
미해결실전! 스프링 데이터 JPA
객체 생성 관련 질문
영한님 안녕하세요.객체 생성과 관련한 내용으로 궁금한 점이 있어 작성하였습니다.객체 생성시 크게 생성자, 빌더, 정적 메소드 3가지 방식으로 알고 있습니다.영한님은 실무에서는 주로 어떤 방식을 선호하는지 궁금합니다.정적 메서드와 빌더를 같이 사용하는건 어떤지 영한님 생각이 궁금합니다. 예시)@Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @NamedEntityGraph( name = "Member.roles", attributeNodes = @NamedAttributeNode(value = "roles", subgraph = "Member.roles.role"), subgraphs = @NamedSubgraph(name = "Member.roles.role", attributeNodes = @NamedAttributeNode("role"))) public class Member extends EntityDate { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "member_id") private Long id; @Column(nullable = false, length = 30, unique = true) private String email; private String password; @Column(nullable = false, length = 20) private String username; @Enumerated(EnumType.STRING) @Column(nullable = false) private SocialType socialType; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) private Set<MemberRole> roles; @Builder public Member(String email, String password, String username, SocialType socialType, List<Role> roles) { this.email = email; this.password = password; this.username = username; this.socialType = socialType; this.roles = roles.stream() .map(r -> new MemberRole(this, r)) .collect(toSet()); } }@Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class MemberDto { private Long id; private String email; private String username; private SocialType socialType; private Set<RoleType> roles; @Builder public MemberDto(Long id, String email, String username, SocialType socialType, Set<RoleType> roles) { this.id = id; this.email = email; this.username = username; this.socialType = socialType; this.roles = roles; } public static MemberDto toDto(Member member) { return MemberDto.builder() .id(member.getId()) .email(member.getEmail()) .username(member.getUsername()) .socialType(member.getSocialType()) .roles(member.getRoles().stream() .map(r -> r.getRole().getRoleType()) .collect(Collectors.toSet())) .build(); } }@Getter @EqualsAndHashCode @NoArgsConstructor(access = AccessLevel.PROTECTED) public class SignUpRequest { @Email(message = "이메일 형식을 맞춰주세요.") @NotBlank(message = "이메일을 입력해주세요.") private String email; @NotBlank(message = "비밀번호를 입력해주세요.") @Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$", message = "비밀번호는 최소 8자리아면서 1개 이상의 알파벳, 숫자, 특수문자를 포함해야합니다.") private String password; @NotBlank(message = "사용자 이름을 입력해주세요.") @Size(min = 2, message = "사용자 이름이 너무 짧습니다.") @Pattern(regexp = "^[A-Za-z가-힣]+$", message = "사용자 이름은 한글 또는 알파벳만 입력해주세요.") private String username; @Builder public SignUpRequest(String email, String password, String username) { this.email = email; this.password = password; this.username = username; } public Member toEntity(Role role, SocialType socialType, PasswordEncoder passwordEncoder) { return Member.builder() .email(email) .password(passwordEncoder.encode(password)) .username(username) .socialType(socialType) .roles(List.of(role)) .build(); } }
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Order와 Item간의 관계에 대해서 궁금한점이 있습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]Order와 Item은 다대다 관계입니다. 하나의 주문이 여러개의 상품을 담을 수 있고, 하나의 상품은 여러개의 주문에 속할 수 있다.여기서 궁금한 점이 있습니다.하나의 상품이 여러 개의 주문이 속할때예를 하나의 상품이라는 객체가 다음과 같이 구성될때id : 1name : 핸드폰stockQuantity : 3categories : 전자제품 이라는 하나의 객체가 주문( id : 2)에도 속하고다른 주문(id:3)에도 속할 수 있다는건가요?
-
미해결스프링 핵심 원리 - 기본편
Provider 사용
package javax.inject; public interface Provider { T get(); } @Autowired private Provider<PrototypeBean> provider; public int logic() { PrototypeBean prototypeBean = provider.get();} Provider 인터페이스 사용시 위처럼 인터페이스를 구현한 구현체 없이도 사용이 가능한가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
AI 답변에 대한 재문의
아!.. 제가 궁금한것은/addForm()에서 생성된 빈 객체가1. addITem 메소드 호출시 바인딩 되는 객체와 동일한 객체인지 와editForm 메소드에서 findById 로 찾는 객체와같은 객체인지 궁금합니다!또한,Item 객체가 단순히 자바빈으로 등록되어있는것이지, 싱글톤은 아니죠?( 꼬리에 꼬리를 무는생각으로 이어진고민입니다.).aI 답변을 받았는데 아직 이해가 잘 가지 않아서 재질문 드립니다!
-
해결됨토비의 스프링 부트 - 이해와 원리
자동 구성 정보 클래스를 작성한다면
@Configuration(proxyBeanMethods = false) static class MyConfig { private final Common common; public MyConfig(Common common) { this.common = common; } @Bean public Bean1 bean1() { System.out.println("bean1 생성자"); return new Bean1(common); } @Bean public Bean2 bean2() { System.out.println("bean2 생성자"); return new Bean2(common); } } @Configuration(proxyBeanMethods = false) static class MyCommonConfig { @Bean public Common common() { return new Common(); } }과@Configuration(proxyBeanMethods = false) static class MyConfig { @Autowired private Common common; public MyConfig() { } @Bean public Bean1 bean1() { System.out.println("bean1 생성자"); return new Bean1(common); } @Bean public Bean2 bean2() { System.out.println("bean2 생성자"); return new Bean2(common); } @Bean public Common common() { return new Common(); } }빈 구성 정보를 프록시 객체로 생성하지 않는다는 대안을 코드로 작성해보면 별도의 구성 정보를 사용하는 방식과내부에서 필드 주입으로 초기화 하는 방식이 생각났습니다. 별도의 구성정보를 사용하면 어떤 클래스를 의존하는지 생성자를 보고 확인할 수 있다는 장점과 테스트 코드를 작성할때 더 편할거라 생각이 들고,밑에 방식은 Common이라는 클래스가 MyConfig 에서만 사용된다면 관리하기도 편할거라 생각이 들었습니다. 그리고 설정 정보 클래스니까 굳이 생성자로 초기화를 하지 않아도 되지 않을까 라는 생각도 들었습니다. 강사님께서 Config 클래스도 테스트를 해봐야한다고 말씀해주셨는데 이런 경우라면 상황에 따라 선택해야하는 부분인가요 ?아니면 설정 정보도 환경에 따라 다를 경우가 있느니까 별도로 분리하는게 나을까요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
postmapping 에서의 모델바인딩 객체
폼에서 작성한 데이터들이 @PostMapping("/add)로 넘어가서 @ModelAttribute 를 통해 item 객체에요청 파라미터를 프로퍼티 접근법으로 값을 세팅하고 모델에 item 객체를 item 의 이름으로 바인딩 되는것이 맞죠?맞다면, @ModelAttribute 를 통해 바인딩 되는 객체는addForm 메소드에서 만들어주어서 타임리프에 활용가능하게 넘겨주었던 그 item 객체인가요?(같은 객체를 재사용하는건지) ,아니면 새로운 객체를 또 만들어서 새로운객체에 값을 세팅해주고 모델에 바인딩을 해주는것인지 궁금합니다 수정폼에서 Item item = itemRepository.findById(itemId); 에서 찾는 item (entity?) 도 addForm 에서 새로 생성했던던 그 객체인것이죠?