묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링부트 시큐리티 & JWT 강의
패스워드 검증은 어디서 이루어지는건가요?
회원가입은 BCryptPasswordEncoder를 통해 패스워드를 암호화를 했었늗데요 @PostMapping("/joinProc") public String joinPorc(User user) { String rawPassword = user.getPassword(); String encPassword = bCryptPasswordEncoder.encode(rawPassword); user.setPassword(encPassword); userRepository.save(user); return "redirect:/login"; }로그인할 떄 에는 따로 패스워드를 따로 검증하지 않고 username만 확인하더라구요@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User userEntity = userRepository.findByUsername(username); if(userEntity != null){ return new PrincipalDetails(userEntity); } return null; } @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }어느 부분에서 자동으로 BCryptPasswordEncoder를 통해 matches하고 검증하는건가요??
-
해결됨스프링 핵심 원리 - 기본편
프록시 객체는 싱글톤인가요?
다른 분들의 질문을 읽어보던중에, 같은 질문에 다른 답변이 달려있는게 있어서 여쭤봅니다."프록시 객체는 각 HTTP 요청마다 생성되는가?" 라는 질문에https://www.inflearn.com/questions/618437 는'각 요청마다 생성된다' 라고 답해져있고https://www.inflearn.com/questions/348888 는'프록시 객체는 한번만 생성된다'(맨밑에 있습니다) 라고 답해져있는데, 뭐가 맞는건가요?그리고, 강의 교안 <9.빈 스코프>의 마지막 페이지(32페이지)에 보면 '마치 싱글톤을 사용하는 것 같지만 다르게 동작하기 때문에 결국에 주의해서 사용해야한다.' 라는 말이 있는데요. 이 말에 대해서 좀 더 설명을 해주셨으면 좋겠습니다. 만약 프록시 객체가 한번만 생성된다면, 그게 싱글톤으로 등록된 것이나 마찬가지인데, 왜 "싱글톤을 사용하는 것 같지만 다르게 동작"하는지 잘 모르겠습니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
타임리프
타임리프를 사용해서 코드를 많이 단축할수 있었는데만약 실무에서 타임리프를 안쓴다면 처음 코드를 모두 구현해야하나요? 아니면 또다른 방법이 있나요?대부분 타임리프를 쓰는지도 궁금합니다
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
프로젝트 생성 질문
앞과정까진 되다가ApplicationTest를 돌리면 이렇게 에러가 나는데 뭐가 잘못된걸까요? package jpabook.jpashop; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class JpashopApplicationTests { @Test void contextLoads() { } }plugins { id 'java' id 'org.springframework.boot' version '2.7.8' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'jpabook' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation("org.junit.vintage:junit-vintage-engine") { exclude group: "org.hamcrest", module: "hamcrest-core" } } tasks.named('test') { useJUnitPlatform() }자바버전은 11이고 스프링부트는 2.7.8로 설치했습니다
-
해결됨토비의 스프링 부트 - 이해와 원리
@Condtional 과 @Condition 질문입니다
강의 제목에 @Conditional 과 @Condition 이라고 나와 있어서 조금 헷갈렸는데애노테이션이나 인터페이스를 표현할 때 @ 를 붙여주는 것이 관례일까요?
-
미해결스프링 핵심 원리 - 기본편
Provider를 이용한 request scope 문제 해결 방법
강의 교안 <9.빈 스코프>의 28페이지를 보면 다음과 같이 설명되어있습니다."ObjectProvider.getObject()를 호출하는 시점까지 request scope 빈의 생성을 지연할 수 있다"이 때, 빈의 생성을 지연한다는 말이 실제로 getObject() 함수를 호출해야만 request scope의 MyLogger 빈이 만들어 진다는 건가요?아니면 http 요청이 들어오는 순간 이미 MyLogger 빈은 다른 로직에 의해 생성되어 존재함이 보장되고, getObject() 함수는 무조건 MyLogger 빈을 갖고 올 수 있기 때문에 이를 논리적으로 "빈의 생성을 지연한다"라고 표현하신 건가요?전자가 맞는지 후자가 맞는지 궁금합니다.*추가. 비슷한 질문이 있어서 해당 질문을 참고하여 내용을 추가하였습니다.https://www.inflearn.com/questions/702458위의 질문에서 "http요청이 들어왔을 때 request bean이 생성되는게 아니라, 생성할수있는 상태가 되는것이고, 이 상태일때 ObjectProvider.getObject()를 하게되면 request bean을 생성한후 반환하는것이다" 라는 답변이 있었습니다. 그래도 이해가 안되서, getObject() 함수가 호출되기 전에 getBean()으로 등록된 MyLogger 빈을 갖고와봤습니다. @Controller @RequiredArgsConstructor public class LogDemoController { private final ObjectProvider<MyLogger> myLoggerProvider; // 추가된 라인 private final ApplicationContext ac; @RequestMapping("log-demo") @ResponseBody public String logDemo(HttpServletRequest request) { // 추가된 라인 MyLogger testMyLogger = ac.getBean(MyLogger.class); // 추가된 라인 System.out.println(testMyLogger); String requestURL = request.getRequestURL().toString(); MyLogger myLogger = myLoggerProvider.getObject(); myLogger.setRequestURL(requestURL); myLogger.log("controller test"); LogDemoService.logic("testID"); return "OK"; } } ApplicationContext를 의존주입 받아서,getObject()가 호출되기 전에 getBean()으로 MyLogger 타입의 스프링 빈을 조회하고 출력하였는데,testMyLogger와 myLogger에 동일한 객체가 들어있었습니다.위의 답변과는 상충되는 결과인데, 제가 추가한 코드에 문제가 있는 건가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
rejectedValue 질문
안녕하세요. 강의 너무 잘 듣고 있습니다.다름이 아니라 bindingResult.rejectValue를 공부하면서의문이 생겼는데요.이 bindingResult.rejectValue가 결국 new FieldError와 같고new FieldError("item", "itemName", null, false, ...);로 들어간다고 하셨는데 3번째 인자에 rejectedValue가 null이라면 오류가 났을 경우 사용자가 입력한 값이복구가 안되고 사라지는 것이 아닌가요?뒤에서 실행한 결과로는 값이 모두 유지되어서 의문이 들었습니다.
-
미해결스프링 핵심 원리 - 기본편
초기화라는 단어
빈 생명주기 콜백 강의를 듣고 질문 남깁니다.public NetworkClient(String url) { this.url = url; }이렇게 생성자에 url을 넘겨주어 값을 지정해주는 것이 초기화 작업이라고 생각하고 강의를 들었는데그러면 문맥상 맞지 않더라고요.가령스프링 빈은 객체 생성, 의존관계 주입이 끝나야 필요한 데이터를 사용할 수 있다.따라서 초기화 작업은 의존관계 주입이 모두 완료되고 호출되어야 한다.이런 부분에서 위 코드와 같은것이 초기화라고 생각한다면 그냥 객체 생성 단계에서 url 값이 지정되었기 때문에 그냥 사용 가능한거 아닌가요?강의에서 말하는 초기화 작업은 정확히 어떤걸 말씀하시는건가요?
-
미해결스프링 핵심 원리 - 기본편
setter 주입을 private으로 선언해도 의존 주입이 되는 이유
수정자 주입과 관련된 질문이 생겨서 글을 쓰게 되었습니다.강의에서 setter를 이용한 의존 주입을 할 때는, setter 함수를 public으로 열어놔야한다고 하셨습니다.만약에 private으로 막아놓으면 어떻게 될지 궁금해서 private으로 막아 놓고 테스트를 돌려보았는데, 여전히 올바르게 의존주입이 되는 결과가 나왔습니다.아무리 생각해봐도 스프링이 private으로 막혀있는 setter 함수를 호출할 수 없을 것 같은데, 어떻게 올바른 의존 주입이 되는 결과가 나온건지 궁금합니다.테스트에 사용한 코드는 아래와 같습니다.// OrderServiceImpl.java package hello.core.order; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import hello.core.discount.DiscountPolicy; import hello.core.discount.FixDiscountPolicy; import hello.core.discount.RateDiscountPolicy; import hello.core.member.Member; import hello.core.repository.MemberRepository; import hello.core.repository.MemoryMemberRepository; @Component public class OrderServiceImpl implements OrderService { private MemberRepository memberRepository; private DiscountPolicy discountPolicy; // ! setter 주입(setter 주입을 사용하려면 final 키워드를 사용할수 없음) @Autowired private void setMemberRepository(MemberRepository memberRepository) { this.memberRepository = memberRepository; } @Autowired private void setDiscountPolicy(DiscountPolicy discountPolicy) { this.discountPolicy = discountPolicy; } @Override public Order createOrder(Long memberId, String itemName, int itemPrice) { Member member = memberRepository.findById(memberId); int discountPrice = discountPolicy.discount(member, itemPrice); return new Order(memberId, itemName, itemPrice, discountPrice); } // 테스트 용도 public MemberRepository getMemberRepository() { return this.memberRepository; } } // AutoAppConfigTest.java package hello.core.scan; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import hello.core.AutoAppConfig; import hello.core.member.MemberService; import hello.core.order.OrderServiceImpl; import hello.core.repository.MemoryMemberRepository; public class AutoAppConfigTest { @Test void basicScan() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class); OrderServiceImpl orderServiceImpl = ac.getBean(OrderServiceImpl.class); System.out.println(orderServiceImpl.getMemberRepository()); } } // AutoAppConfig.java package hello.core; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; @Configuration @ComponentScan(basePackages = "hello.core", basePackageClasses = AutoAppConfig.class, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)) public class AutoAppConfig { }
-
미해결스프링 핵심 원리 - 기본편
@Configuration과 @ComponentScan의 충돌
안녕하세요. @ComponentScan을 공부하다가 궁금한게 생겨서 질문드립니다.@ComponentScan에 의해서 @Configuration 이 붙은 클래스를 스캔했을 때, 이 때 만들어진 스프링 빈도 팩토리 빈의 역할을 하게 되나요?예를 들어,AppConfig 라는 클래스에 @Configuration을 붙이고 내부에 @Bean을 이용해 등록할 빈들을 만들어놓는다.AutoAppConfig 라는 클래스에 @ComponentScan을 붙이고 스프링 컨테이너(ApplicationContext)에 AutoAppConfig.class 로 설정정보를 넘겨준다.위와 같이 했을 때, AutoConfig가 스프링 빈으로 등록되고 @ComponentScan에 의해 스캔이 시작되어, AutoAppConfig가 위치한 패키지부터 하위 패키지까지 스캔되어 스프링 빈이 등록 될 것입니다. (AppConfig는 패키지 내부에 속해있어 스캔된다고 가정하겠습니다.)그럼 이 경우에 exclude 필터로 @Configuration에 해당하는 클래스를 제외하지 않는다면, AppConfig도 스프링 빈으로 등록될텐데,스프링 컨테이너(ApplicationContext)에 직접적으로 AppConfig.class와 같은 설정 정보를 전달하지 않았는데, 이때도 AppConfig가 팩토리 빈이 되어, 위의 1번에서 @Bean으로 만들어놓은 빈들을 스프링 컨테이너가 등록하게 되는지 궁금합니다.
-
해결됨토비의 스프링 부트 - 이해와 원리
[스프링 컨테이너 사용] 강의 중 getBean IDE 상 에러가 뜨는데 원래 그럴까요 ?
cannot acess 에러가 발생하는데,실제, 코드를 돌리면 컴파일 및 런타임 에러 없이 동작합니다.Access 에러 길래, 접근 제어자 문제로 판단하였으나, 전부 Public 이라 딱히 문제도 없는것 같은데, 저만 그런건지 궁금합니다.registerBean 에서도 해당 클래스를 불러오기 때문에, 여기서도 에러가 뜬다면 이해하겠으나..해당 부분은 문제없고.. 밑에서만 떠서... 궁금합니다[참고로, 실행하면 컴파일 에러 없이 실행 되고... IDE 상에서는 에러로 계속 남아 있습니다. ] package com.example.helloboot; import org.apache.catalina.startup.Tomcat; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.support.GenericApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class HellobootApplication { public static void main(String[] args) { // Spring Container 생성 Context 가 Container 임 // 컨테이너 생성 GenericApplicationContext applicationContext = new GenericApplicationContext(); // 오브젝트 (빈) 등록 applicationContext.registerBean(HelloController.class); // 오브젝트 생성 요청 applicationContext.refresh(); // [Step 1] Servlet 컨테이너 생성 // Factory 생성과 설정 작업등을 대신 해주는 대상 TomcatServletWebServerFactory serverFactory = new TomcatServletWebServerFactory(); WebServer webServer = serverFactory.getWebServer(servletContext -> { servletContext.addServlet("frontcontroller", new HttpServlet() { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 인증, 보안 , 다국어, 공통 기능 등 처리 if (req.getRequestURI().equals("/hello") && req.getMethod().equals(HttpMethod.GET.name())) { String name = req.getParameter("name"); // binding 데이터를 처리하는 오브젝트에 데이터를 넘기는 것 HelloController helloController = applicationContext.getBean(HelloController.class); String ret = helloController.hello(name); resp.setContentType(MediaType.TEXT_PLAIN_VALUE); resp.getWriter().println(ret); } else { resp.setStatus(HttpStatus.NOT_FOUND.value()); } } }).addMapping("/*"); }); webServer.start(); } }
-
해결됨스프링 핵심 원리 - 기본편
@RequiredArgsConstructor
@RequiredArgsConstructor 사용할 때, 추가 생성자를 작성하면, @RequiredArgsConstructor에 의해 자동으로 만들어진 생성자에는 @Autowired를 따로 추가해줘야하나요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
스프링 빈(Bean) 개념 관련 질문
스프링 bean 관련 공부를 하던중 구글링을 통해 정리를 해보려 했지만 헷갈려서 질문드립니다.spring container가 빈을 생성하고 생성자가 여러차례 호출되어도 실제로 생성되는 객체는 하나이며 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 가르킨다고 알고있는 상태입니다.제가 알고 있는 부분이 맞는지 그러면 test class에서 @beforeEach에 객체를 테스트 실행전 매번 새로 생성하는데 이것은 사실 결국은 하나의 최초객체를 가르킨다는 얘기인가요???
-
미해결스프링 핵심 원리 - 기본편
ObjectProvider를 Singleton으로 사용하지 않는가?
ObjectProvider 를 이용해 request scope 빈과 관련된 문제를 해결하는 과정에서 궁금한 것이 생겨 질문드립니다.교안에서 LogDemoController 와 LogDemoService 는 각각 필드로 ObjectProvider<MyLogger> 를 갖고 있는데요.실제로 애플리케이션을 동작시켜 출력해보니, LogDemoController 와 LogDemoService가 서로 다른 ObjectProvider 객체를 사용하고 있었습니다.ObjectProvider<MyLogger> 를 싱글톤으로 사용하지 않는 이유가 있을까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Spring 초기 생성에서 버전이 강의와 다릅니다.
현재 https://start.spring.io/ 에 접속하며 나오는 버전입니다.강의에서는 2.3.x 버전인데 여기서는 없어서 2.7.8 로 진행했습니다.이대로 진행해도 문제 없을까요?아니면 여기서 spring boot 버전을 따로 설정하는 방법이 있나요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@ModelAttribute로 받은 객체의 API 예외 처리
안녕하세요. @ControllerAdvice로 예외처리를 하는 부분에서 궁금증이 생겨 질문남기게 되었습니다.@RequestBody를 통해 값을 받는 요청들은@ExceptionHandler(MethodArgumentNotValidException.class) 설정을 통해서 예외처리를 할 수 있는데, @ModelAttribute를 통해서 값을 받는 요청들은 ControllerAdvice에서 어떠한 Exception을 통해 걸러서 예외처리를 해야하는지 감이 잡히지 않습니다.@ModelAttribute를 통해 값을 받는 경우 어떠한 방식으로 공통예외처리를 할 수 있는 걸까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
인텔리제이 실행이안되요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]갑자기 화면에 저것만 계속뜨고 실행되지않아요,, 지우고 깔아봤는데도..
-
해결됨스프링 핵심 원리 - 기본편
싱글톤빈에 항상 새로운 프로토타입빈을 주입하는 방법
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요. 싱글톤빈에 항상 새로운 프로토타입빈을 주입하는 방법에 대해 생각해보았는데요. 혹시 이 방법은 사용하면 안되는걸까요??logic을 실행하기 전 new PrototypeBean이 생성돼서 항상 1이 반환됩니다.static class ClientBean { private PrototypeBean prototypeBean; public int logic() { this.prototypeBean = new PrototypeBean(); this.prototypeBean.addCount(); return this.prototypeBean.getCount(); } }
-
해결됨스프링 핵심 원리 - 기본편
스프링 컨테이너 라이프사이클 질문입니다.
10: 07초에 보시면스프링 컨테이너는 크게 두가지 라이프사이클 있다라고 말씀하셨는데1. 스프링 빈 등록 단계- 생성자에 @Autowired는 이때 자동적으로 의존관계 주입2. 의존관계 설정 단계 (Autowired가 걸린애를 자동으로 주입)- 수정자에(setter) @Autowired는 이때 자동적으로 의존관계 주입이렇게 이해를 했는데 맞는지 궁금합니다.답변주시면 정말 감사하겠습니다.
-
해결됨스프링 핵심 원리 - 기본편
@Autowired 관련 질문입니다.
다른분 질문에서안녕하세요. g g님, [공식 서포터즈](https://www.inflearn.com/blogs/617) David입니다.자동 빈 등록, 자동 의존관계 주입은 수동 빈 등록, 수동 의존관계 주입을 애노테이션 몇가지를 통해 대체해 주는 게 핵심입니다.이 과정에서 @ComponentScan, @Component, @Autowired 같은 애노테이션이 사용되거나 필요로 합니다.그 중 @Autowired 는 자동 빈 등록에 해당합니다.이런 글이 있었는데 (아래 코드를 예시로 들겠습니다)@Component public class MemberServiceImpl implements MemberService{ //구현 객체를 선택해줘야함 아님null값 private final MemberRepository memberRepository; @Autowired //ac.getBean(MemberRepository.class) 와 비슷(Autowired가 더 기능이 있음) public MemberServiceImpl(MemberRepository memberRepository) { this.memberRepository = memberRepository; }저는 @ComponentScan 이 @Component 가 붙은 MemberServiceImpl 클래스와 memberRepository를 스프링 빈으로 등록하고 그 다음에 생성자에 @Autowired가 자동으로 MemberServiceImpl 과 의존관계를 가지는 memberRepository(스프링 빈)을 타입으로찾아서 의존 관계를주입한다.getBean(MemberRepository.class) 와 비슷(Autowired가 더 기능이 있음)라고 이해하고 있었는데 @Autowired도 빈을 등록하는 것인가요?제가 예시로 든 코드에서 생각하는 과정이 맞는건가요??