묻고 답해요
169만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
[해결방법] Could not autowire. No beans of 'ItemMapper' type found. 오류
아래 코드 추가@MapperScan("hello.itemservice.repository.mybatis") @Configuration @RequiredArgsConstructor @MapperScan("hello.itemservice.repository.mybatis") public class MyBatisConfig { private final ItemMapper itemMapper; @Bean public ItemService itemService() { return new ItemServiceV1(itemRepository()); } @Bean public ItemRepository itemRepository() { return new MyBatisItemRepository(itemMapper); } }
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
[해결방법] Invalid bound statement 오류
resources 폴더에서 폴더를 하나씩 생성해야합니다.한번에 폴더를 생성하면 오류가 발생합니다. (예: hello.iteamservice.repository.mybatis)강사님 만들어두신 프로젝트의 폴더를 복사 붙여넣기해도 오류가 발생합니다. 올바른 예시)hello 폴더 생성itemservice 폴더 생성repository 폴더 생성mybatis 폴더 생성ItemMapper.xml 파일 생성
-
미해결실전! 스프링 데이터 JPA
17:00 분 경에 적으시는 @Bean은 꼭 main메서드가 있는 곳에서 작성해야 하나요>?
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]혹시 config클래스를 따로 파서 거기에 만들어도 적용이 되는 건가여? 만약에 된다고 하면 둘중 어떤 식으로 많이 사용하나요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
p6spy와 r2dbc 관련 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요. 지금 엔티티 클래스 개발2 강의 수강 중입니다.해당 강의 7분 20초 즈음 JpashopApplication 클래스 실행시키는 부분에서 런타임 에러가 발생하여 질문을 올리게 됐습니다. 처음 뜬 오류는 Caused by: java.lang.IllegalStateException: Could not evaluate condition on com.github.gavlyukovskiy.boot.jdbc.decorator.flexypool.FlexyPoolConfiguration$PropertyFlexyConfiguration due to com/vladmihalcea/flexypool/util/ClassLoaderUtils not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake) 이었습니다. 구글링과 chatgpt를 사용해 해결방법을 모색하였고 p6spy를 사용하려면 flexypool이 필요없다는 사실을 확인 했지만 오류 메세지에 맞추어implementation 'com.github.gavlyukovskiy:flexy-pool-spring-boot-starter:1.9.0' 을 build.gradle에 추가해 해결하려고 했습니다. 하지만 이번에는 'Caused by: java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryConfigurations$PoolConfiguration due to io/r2dbc/spi/ValidationDepth not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)' 오류가 발생하는 걸 확인할 수 있었습니다. 이번에도 구글링 및 chatgpt를 통해 해결방법을 찾아보려 했는데, JPA를 사용하면 R2DBC 관련한 모듈을 추가할 필요가 없다는 걸 확인할 수 있었고 아예 잘못된 방향으로 해결방법을 모색하고 있다는 걸 확인했습니다. 3. 현재 작성중인 코드에 flexy-pool을 사용하는 코드가 있나 점검해보았습니다. ./gradlew clean build .application.yml 점검build.gradle 점검./gradlew dependencies 를 통해서 의존관계 확인하지만 문제가 되는 부분을 찾을 수는 없었습니다. 어디서부터 잘못된건지, 해결 방법은 무엇인지 알려주시면 감사하겠습니다. 파일 링크 : https://drive.google.com/file/d/1kWHwYUf8akxBlG1Wdn6D_1WQbnRw8uzR/view?usp=sharing감사합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ExceptionResolver 내에서 sendError 호출
안녕하세요! 제가 질문의 의도를 명확히 드러내지 못한 것 같아 내용을 추가하여 재 질문 드립니다. https://www.inflearn.com/community/questions/1369485/exceptionresolver-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC-%EC%A7%88%EB%AC%B8%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4 <제가 생각한 json 결과> { "timestamp": "2024-09-07T16:52:16.664+00:00", "status": 400, "error": "Bad Request", "path": "/api/members/bad" } resolver에서 IllegalArgumentException을 해결을 하였고 sendError로 흐름을 바꾸었으니 순수 sendError(400)의 결과인 위 json과 같이 나와야 한다고 생각하였습니다.<흐름도>Controller 에서 IllegalArgumentException 발생 -> ExceptionResolver 실행 -> IllegalArgumentException 해결 후 sendError로 변경 -> BasicController 호출 후 sendError의 결과인 위의 json 반환 따라서 에러를 해결하였기 때문에 IllegalArgumentException 정보는 없고 sendError 정보만 있다고 생각합니다. 실제 출력에는 어찌 IllegalArgumentException 정보가 json에 출력되는지 궁금합니다. 에러를 해결 했더라도 그 정보를 다른 객체로 가지고 있고 나중에 활용하는 것 일까요?? 좋은 강의 만들어 주셔서 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
update 로직 질문
멤버 업데이트 시memberService.update(id, request.getName());으로 작성해 주셨는데memberService.update(id, request);와 같이 객체를 통째로 넘기지 않는 이유가 있는 것인가요? 위와 같이 객체를 통째로 넘기는 경우 UpdateMemberRequest 클래스를 이너 클래스가 아닌 별도의 클래스로 분리해 줘야 하는 게 맞나요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
JdbcMemberRepository 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.어떤 점이 문제인지 모르겠습니다 ㅜ jdbcMemberRepositorypackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import org.springframework.jdbc.datasource.DataSourceUtils; import javax.sql.DataSource; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; public class JdbcMemberRepository implements MemberRepository{ private final DataSource dataSource; public JdbcMemberRepository(DataSource dataSource) { this.dataSource = dataSource; } @Override public Member save(Member member) { String sql = "insert into member(name) values(?)"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, member.getName()); pstmt.executeUpdate(); rs = pstmt.getGeneratedKeys(); if (rs.next()) { member.setId(rs.getLong(1)); } else { throw new SQLException("id 조회 실패"); } return member; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findById(Long id) { String sql = "select * from member where id = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setLong(1, id); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } else { return Optional.empty(); } } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public List<Member> findAll() { String sql = "select * from member"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); List<Member> members = new ArrayList<>(); while(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); members.add(member); } return members; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findByName(String name) { String sql = "select * from member where name = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } return Optional.empty(); } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } private Connection getConnection() { return DataSourceUtils.getConnection(dataSource); } private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (pstmt != null) { pstmt.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn != null) { close(conn); } } catch (SQLException e) { e.printStackTrace(); } } private void close(Connection conn) throws SQLException { DataSourceUtils.releaseConnection(conn, dataSource); } } MemberRepositorypackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import java.util.List; import java.util.Optional; public interface MemberRepository { Member save(Member member); void finById(Long id); Optional<Member> findById(Long id); Optional<Member> findByName(String name); List<Member> findAll(); void cleatStore(); }MemoryMemberRepositorypackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import java.util.Map; import java.util.Optional; import java.util.*; public class MemoryMemberRepository implements MemberRepository { public static Map<Long, Member> store = new HashMap<>(); private static long sequence = 0L; @Override public Member save(Member member) { member.setId((++sequence)); store.put(member.getId(), member); return member; } @Override public void finById(Long id) { } @Override public Optional<Member> findById(Long id) { return Optional.ofNullable((Member) store.get(id)); } @Override public Optional<Member> findByName(String name) { return store.values().stream() .filter(member -> member.getName().equals(name)) .findAny(); } @Override public List<Member> findAll() { return new ArrayList<>(store.values()); } @Override public void cleatStore() { } void clearStore() { store.clear(); } }errorerror: JdbcMemberRepository is not abstract and does not override abstract method cleatStore() in MemberRepository public class JdbcMemberRepository implements MemberRepository{
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
JdbcMemberRepository 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.이런 오류가 뜨는데 대체 어떻게 해결해야 할까요? ㅠㅠpackage hello.hello_spring.repository; import hello.hello_spring.domain.Member; import org.springframework.jdbc.datasource.DataSourceUtils; import javax.sql.DataSource; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Optional; public class JdbcMemberRepository implements MemberRepository{ private final DataSource dataSource; public JdbcMemberRepository(DataSource dataSource) { this.dataSource = dataSource; } @Override public Member save(Member member) { String sql = "insert into member(name) values(?)"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, member.getName()); pstmt.executeUpdate(); rs = pstmt.getGeneratedKeys(); if (rs.next()) { member.setId(rs.getLong(1)); } else { throw new SQLException("id 조회 실패"); } return member; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findById(Long id) { String sql = "select * from member where id = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setLong(1, id); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } else { return Optional.empty(); } } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public List<Member> findAll() { String sql = "select * from member"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); List<Member> members = new ArrayList<>(); while(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); members.add(member); } return members; } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } @Override public Optional<Member> findByName(String name) { String sql = "select * from member where name = ?"; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); rs = pstmt.executeQuery(); if(rs.next()) { Member member = new Member(); member.setId(rs.getLong("id")); member.setName(rs.getString("name")); return Optional.of(member); } return Optional.empty(); } catch (Exception e) { throw new IllegalStateException(e); } finally { close(conn, pstmt, rs); } } private Connection getConnection() { return DataSourceUtils.getConnection(dataSource); } private void close(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (pstmt != null) { pstmt.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn != null) { close(conn); } } catch (SQLException e) { e.printStackTrace(); } } private void close(Connection conn) throws SQLException { DataSourceUtils.releaseConnection(conn, dataSource); } } error: JdbcMemberRepository is not abstract and does not override abstract method cleatStore() in MemberRepository public class JdbcMemberRepository implements MemberRepository{
-
해결됨Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부
Reactor 3부의 오픈 일정에 관해서 문의드립니다!
안녕하세요 최근에 Spring MVC 말고도 Spring WebFlux에 대해서도 관심을 가지게 되어 Reactor 공부를 막 시작한 주니어입니다. 해당 강의가 3부까지 기획되어 있는 것으로 강의소개를 봤었습니다. 강사님께서도 무척이나 바쁘시겠지만, 혹시 3부는 언제쯤 오픈할 예정이신지 여쭤봐도 될까요? 강의 잘 보고 있습니다! 감사합니다
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
response.sendError의 역할
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]섹션 8에서 컨트롤러에서 response.sendError()을 사용해서 WAS까지 오류 정보를 전달 하는 것으로 생각했습니다.그런데 섹션 9를 공부하면서 ExceptionResolver 코드를 확인해보면 결국 내부적으로 response.sendError() 를 호출한 다는 것을 알게 되었습니다.이는 response.sendError()를 사용하는 것이 WAS까지 오류 정보를 전달하는 역할을 하는 것이 아니라고 이해하면 될까요? 그렇다면 어떻게 위 그림의 sendError흐름이 만들어지는 걸까요
-
해결됨토비의 스프링 6 - 이해와 원리
멀티 스레드를 사용하는 테스트에서 트랜잭션 사용에 대해서..
멀티 스레드를 사용하는 테스트에서는 @Transactional 을 어떻게 사용해야 할까요..? 동시성 이슈를 확인하는 테스트에서는 주로 ExecutorService 를 통해 스레드 풀을 생성해서 동시에 서비스 로직을 호출하는 식으로 테스트를 진행하면서 여러 문제를 겪었는데 어떻게 해결하면 좋을지 고민을 하다가 토비님에게 질문드려봅니다 ㅠㅠ다른 스레드에서 save() 한 오브젝트를 조회할 수 없는 문제.테스트 코드에 @Transactional 를 사용하게 되면 테스트 코드가 하나의 트랜잭션으로 묶이게 되는데, 다른 스레드에서 서비스를 호출 하기 전에 테스트를 위한 데이터를 save() 하고 다른 스레드가 서비스에서 save 한 데이터를 가져오려고 할 때 아직 DB에 commit 되지 않은 상태여서 가져오지 못하는 이슈가 있더라구요. -> db isolation level이 read uncommited 보다 높기 때문에 발생하는 것 같음. @Test @DisplayName("밖에서 저장한 데이터는 스레드 내부에서 가져올 수 없음") @Transactional void outsideTransaction() throws InterruptedException { Member member = new Member(1L, "테스트유저"); memberRepository.saveAndFlush(member); entityManager.clear(); TimeUnit.SECONDS.sleep(2); // 일정 시간 대기. try (ExecutorService executorService = Executors.newFixedThreadPool(32)) { executorService.submit(() -> { long count = memberRepository.count(); Optional<Member> optionalMember = memberRepository.findById(1L); System.out.println("member count: " + count); System.out.println("optionalMember.isEmpty: " + optionalMember.isEmpty()); }); } System.out.println("================================="); long count = memberRepository.count(); Optional<Member> optionalMember = memberRepository.findById(1L); System.out.println("member count: " + count); System.out.println("optionalMember.isEmpty: " + optionalMember.isEmpty()); }member count: 0 optionalMember.isEmpty: true ================================= member count: 1 optionalMember.isEmpty: false테스트 코드에 @Transactional 을 선언해도 테스트 코드 내부에서 생성한 스레드에서는 트랜잭션이 존재하지 않는 문제. @Test @DisplayName("내부 스레드는 트랜잭션이 존재하지 않음.") @Transactional void activeTransaction() { System.out.println("쓰레드 밖에서 트랜잭션 상태: " + TransactionSynchronizationManager.isActualTransactionActive()); try (ExecutorService executorService = Executors.newFixedThreadPool(32)) { executorService.submit(() -> { System.out.println("쓰레드 안에서 트랜잭션 상태: " + TransactionSynchronizationManager.isActualTransactionActive()); }); } } 위와 같은 테스트를 실행 했을 때, 출력되는 결과는 다음과 같았습니다.쓰레드 밖에서 트랜잭션 상태: true 쓰레드 안에서 트랜잭션 상태: false멀티 스레드를 사용하는 테스트에서 @Transactional 를 사용 했을 때 이런 문제점이 있었는데요.. 여러가지 시도해보다가 해결을 하지 못해서 결국 @Transactional 을 사용하지 않고.. 테스트가 끝날 때 마다 @AfterEach 통해서 DB를 직접 제거하는 방식으로 하고 있습니다... 이렇게 테스트는 @Transactional 을 사용하지 않고 서비스 로직에는 @Transactional 사용하고 있다보니, 실제 애플리케이션을 띄워서 api 부하 테스트를 해보면 원하는 결과가 나오지 않았습니다. 테스트 코드가 테스트 코드의 역할을 수행하고 있지 않네요이런 경우에는 어떻게 해결하는 것이 좋을까요? 감사합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
jsp 페이지 인식 안되는 문제
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요.jsp 페이지가 인식되지 않습니다./jsp/members/new-form.jspgradle gradle 적용후 새로 적용했고 했고 서버도 재시작 했는데 jsp 페이지 접근이 안됩니다.index.html 정상 접근됩니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Spring web bean validation 에러핸들링
Bean validation핸들링이 보통 어떤 설계가 일반적인지 알고싶어서 질문드립니다폼post 송신시, Bean validation으로 에러감지 후 입력화면html로 리턴할텐데요이때, 브라우저 url은 post송신용이 남아있어서유저가 브라우저 주소창 엔터로Get으로 송신이 되어 서버에선postmapping만 지원한다고 시스템에러가 나는데 일반적으로 이런건 유저가 개발자 의도와는 다르게 이용한 케이스겠지만 흔히 있을 수 있는 일 같거든요. 이런거 방지하기 위해서는 get도 받을 수 있게 따로 구현을 하나요?아니면 실무에서는 어떤 방법이 있을까요
-
미해결토비의 스프링 6 - 이해와 원리
인터페이스는 사용하는 클래스에 가장 가까이 두는 걸로 이해했습니다. 하지만 그 인터페이스를 사용하는 클라이언트가 많다면 어떻게 해야할까요?
강의 재밌게 잘 보고 있습니다.궁금한 게 있어 질문드립니다.인터페이스는 구현체와 같은 모듈에 두는 게 아닌, 사용하는 클래스에 가장 가까이 두는 걸로 이해했습니다. 하지만 그 인터페이스를 사용하는 클라이언트가 많다면 어떻게 해야할까요?예를 들어 Payment 패키지의 PaymentService 도 ExRateProvider 를 쓰고,XXX 패키지의 XXXService 도 ExRateProvider 를 쓴다면ExRateProvider 의 모듈 위치는 어디에 존재를 해야할까요? 아니면 다른 방법이 있을 듯 한데, 그 방법은 무엇일까요?ExRateProvider 의 모듈 위치가 클라이언트와 분리되어 있다면, DIP 적용 이전 그러니까 WebApiExRateProvider 와 ExRateProvider 가 한 모듈에 같이 위치한 그림과 별반 다를 것이 없다(모듈 의존성에 따른 변경 가능성) 생각이 들어서요
-
미해결스프링 핵심 원리 - 기본편
이상한 에러가 발생했습니다
jdk 22를 사용중입니다.증상은 위의 에러가 뜨는데 테스트 코드들은 정상적으로 초록 채크표시가 뜹니다. 이거 무슨 에러인가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ItemController
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]1. ItemController에서 downloadImage함수에서 @ResponseBody를 사용하였는데, 사용하지않게 되면, 예외가 발생합니다. 왜그런가요?ItemController에서 downloadAttach에서는 ResponseEntity<Resource>를 사용하셨는데, 이게 @ResponseBody와 같은거라고 하셨는데,( 다만, header에 추가할 부분이 있어서 ResponseEntity를 사용하셨다고 하는데) 어떤 부분이 같은 건가요?
-
미해결스프링 시큐리티 OAuth2
OAuth 2.0 Grant Flows 관련 질문
안녕하세요. OAuth 2.0을 배우고 싶어 학습 신청했습니다.유익한 강의 준비해주셔서 감사합니다.막연하게 알고 있는 Spring Security 에 대해 강의를 통해 명확하게 알아가고 있습니다. 강의를 들으며 몇가지 궁금한 점이 있어 질문드립니다. 우선은 자체 로그인만 구현할 예정이라면,소셜 로그인 기능이 없는 경우에는 OAuth 2.0을 도입할 필요가 없는 건가요?Resource Owner Password Credentials Grant Flow 는 Deprecated 된다고 하는데 그럼 어떻게 구현해야하나요? 답변주시면 성장하는데 큰 도움이 될 것 같습니다!감사합니다!
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
엔티티 조회와 DTO조회
엔티티 조회를 권장하신다고 했는데 엔티티 조회로 처리 안 되는 경우가 있나요? 엔티티로 조회한 결과를 DTO로 변환해서 넘기는게 가장 좋은 방법 아닌가요??
-
해결됨스프링 핵심 원리 - 기본편
call AppConfig.memberRepository가 왜 두번 더 호출되나요?
11:47부터 //call AppConfig.memberService //call AppConfig.memberRepository//call AppConfig.memberRepository//call call AppConfig.orderService//call AppConfig.memberRepository처럼 보인다했는데//call AppConfig.memberRepository//call AppConfig.memberRepository가 //call AppConfig.memberService후 에 두번 호출되는것처럼 보인다는건가요?//call call AppConfig.orderService호출 후 한번 call AppConfig.memberRepository출력된것처럼 보이는거아닌가요??왜 memberService일때는 왜 레포지토리가 두번 호출되는것처럼 보이나여ㅛ?
-
미해결스프링 핵심 원리 - 기본편
AutoAppConfig의 memberRepository() 반환 유형에 따른 충돌 여부
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.AutoAppConfig의 memberRepository() 반환 타입을 아래와 같이 인터페이스로 했을때는 충돌이 발생했습니다. 그런데@Configuration @ComponentScan( basePackages = "hello.core", excludeFilters=@ComponentScan.Filter(type= FilterType.ANNOTATION,classes=Configuration.class) ) public class AutoAppConfig { @Bean(name="memoryMemberRepository") MemberRepository memberRepository(){ return new MemoryMemberRepository(); } }해당 함수의 반환 타입을 아래와 같이 실제 구현체 클래스인 MemoryMemberRepository로 하니까 test 시 충돌이 발생하지 않습니다. 빈이름이 같으면 반환타입을 인터페이스로 하든, 그 구현체로 하든 충돌이 발생해야된다고 생각했는데 왜 실제 구현체로 하면 충돌이 발생하지 않나요?@Configuration @ComponentScan( basePackages = "hello.core", excludeFilters=@ComponentScan.Filter(type= FilterType.ANNOTATION,classes=Configuration.class) ) public class AutoAppConfig { @Bean(name="memoryMemberRepository") MemoryMemberRepository memberRepository(){ return new MemoryMemberRepository(); } }