묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
싱글톤 강의
싱글통 강의에서 숙제에 대한 답변도 볼 수있는 곳이 있을까요?
-
미해결김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션
UTF-8 문자열을 char 타입으로 변경하는것에 대해서 궁금합니다.
public static void main(String[] args) throws IOException { String writeString = "가나다ABC"; System.out.println("writeString = " + writeString); // 파일에 쓰기 var fw = new FileWriter(FILE_NAME, StandardCharsets.UTF_8); fw.write(writeString); fw.close(); // 파일에서 읽기 var content = new StringBuilder(); var fr = new FileReader(FILE_NAME); int ch; while ((ch = fr.read()) != -1) { char ch1 = (char) ch; System.out.println("ch1 = " + ch1); content.append(ch1); } fr.close(); System.out.println("readString = " + content); } 질문1) 예제의 코드에서 char ch1 = (char) ch; 로 캐스팅하는부분이 궁금해요인코딩이 UTF-8 이니 최대 3바이트까지 쓸 수 있는데 이것을 2바이트만쓰는 char 로 캐스팅할 수 있는 이유는 무엇인가요?가~다 는 자바의 기본인코딩타입인 UTF-16 에서 2바이트로 표현할 수 있기 때문일까요?fr.read() 는 2바이트로 표현해야하는것이 아니라면 해당문자열까지 읽고, 반환하는것으로보이는데 맞는걸까요?확인해보니 이모지같은경우에는 UTF-16 에서는 두 바이트로 표현이힘들어서 깨지는것을 확인했습니다! 질문2) 위의 가정이 맞다면 Reader, Writer 은 항상 JVM이 관리하는 UTF-16 으로 읽는과정이 있으니 byte 단위로 읽는 Stream 보다 성능적으로 느릴 것 같은데 맞을까요?
-
미해결김영한의 실전 자바 - 중급 1편
클래스 접근제어자
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]앞서 기본편 강의에서 JAVA의 클래스 접근제어자는 public,default만 사용하다고 배웠는데, 정적 중첩 클래스에는 예외적으로 private 사용이 가능한건가요? Oracle docs를 찾아봤는데 해당 내용이 안보여서 질문드립니다.
-
해결됨오브젝트 - 기초편
DiscountCondition을 DiscountPolicy 뒤에 숨겨야 하는 이유
안녕하세요 선생님 강의 잘보고 있습니다 !.강의 내용 중 "DiscountPolicy가 Discount Condition을 포함하기 때문에 Discount Policy뒤로 Discount Condtion을 숨기고 Reservation Service가 Discount Policy에만 의존할 수 있도록 코드를 바꾼다"라고 하신 부분이 있는데 DiscountCondition을 숨겨야하는 이유에 대해서는 이해를 했는데 DiscountCondition을 DiscountPolicy 뒤에 숨겨야 하는 이유에 대해서는 이해가 잘 안됩니다.DiscountPolicy에 왜 DiscountCondition을 저장한 List를 포함하는 것인지 잘모르겠습니다.코드를 짜다보면 자연스럽게 이해가 갈까요 ? ㅜ ㅜ 객체지향이 정말 어려운 개념인 것 같습니다.
-
미해결김영한의 실전 자바 - 중급 1편
New ImmutableAddress부분의 질문입니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.MemberB.setAddress(New ImmutableAddress("부산")); 이부분이 ImmutableAddress address2 = New ImmutableAddress("부산"); memberB.setAddress(address2);이코드와 같은 건가요?
-
미해결스프링 핵심 원리 - 기본편
자바 설치
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용사전 준비물에 이렇게 있ㄴ느데IntelliJ 안에서 프로젝트 생성할때 설치하는 open JDK 와 자바 설치는 무관한 것인가요?자바를 따로 설치하지 않아도 지금까지는 문제가 없었는데 설치가 필요할까요?Open JDK 와 자바는 무슨 차이 인지 모르겠어요! 저는 현재이건 자바를 설치하지 않은 상태이죠?
-
해결됨기초 탄탄! 독하게 시작하는 Java - Part 2 : OOP와 JVM
예외 처리 강의 내용 관련 질문
안녕하세요 선생님섹션 11의 예외 처리 강의 중 [두 가지 예외 종류] 파트를 공부하다가 궁금증이 생겨서 질문드립니다. Checked Exception과 Unchecked Exception을 Exception 클래스의 파생이냐, 혹은 RuntimeException의 파생이냐에 따라 분류하는 것으로 설명해주신 것으로 이해했는데요. 그런데 1.4v 교안 기준으로 305페이지에(강의 기준으로 2분 32초) Unchecked exception 열에서 사례를 들어주신 SQLException, IOException, ClassNotFoundExcpetion은 jdk를 확인해보니 Exception의 파생이었습니다.(ReflectiveOperationException은 Exception 클래스의 파생입니다.)jdk 코드를 기준으로 보면 SQLException, IOException, ClassNotFoundExcpetion은 Checked Exception에 해당하는 것으로 보이는데, 선생님께서 해주신 설명과 다른 부분이 있어서 혼동이 오는데 어떤게 맞는건지요? 그리고 강의 내용을 바탕으로 좀 더 공부를 해보니 제가 이해한 바는 아래와 같습니다. 혹시 잘못 이해한 부분이이 있을까요?1. Checked, Unchecked Exception 모두 예외 발생은 Runtime에서 이루어진다.2. 파일 I/O, DB 접근은 실행 환경에서 자주 발생할 수 있는 문제이기 때문에, 개발자가 이를 예상하고 처리하도록 컴파일 시점에서 컴파일러에 의해 예외처리가 강제된다. -> SQLException, IOException 예외가 Checked Exception인 이유 감사합니다.
-
미해결김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
스케줄링에 대한 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]프로세스 스케줄링과 스레드 스케줄링의 차이에 대해 궁금합니다. 두가지는 동일한 개념인가요? 1개의 CPU 코어는 한번에 하나의 스레드만 실행할 수 있나요?
-
해결됨오브젝트 - 기초편
영화 예매 도메인 코드 작성
안녕하세요 선생님 강의 너무 잘보고 있습니다.강의에 대한 질문은 아니고 궁금한게 생겨 질문글 남깁니다.영화 예매 도메인을 처음부터 코드를 짠다고 작성하면 어느 부분부터 작성하는 것이 좋을까요 ?좋은 강의 해주셔서 감사합니다 !
-
해결됨기초 탄탄! 독하게 시작하는 Java - Part 2 : OOP와 JVM
[JVM이 문자열 상수를 관리하는 구조] 관련 질문드립니다.
안녕하세요 선생님~[JVM이 문자열 상수를 관리하는 구조] 강의를 듣던 중에 이해가 잘 안되는 부분이 있어서 질문드립니다. 제가 기존에 알고 있던 내용과 더불어 강의를 통해 이해한 바로는1. "런타임 상수 풀"은 문자열 리터럴 객체가 아닌 문자열 리터럴의 심볼릭 참조를 저장하는 곳, 즉 실제 객체는 저장되지 않음 - 물론 여러 다른 심볼릭 참조 또한 저장됨2. String s1 = "Hello"처럼 리터럴로 선언된 String instance는 Heap 메모리 영역의 "문자열 상수 풀"에 저장3. String s3 = new String("Hello")는 객체로, Heap 메모리 영역이면서 문자열 상수 풀이 "아닌" 영역에 저장. 즉, 문자열 상수 풀에 독립적4. 따라서 문자열 상수 선언(String s1 = "Hello") 또는 intern() 메서드 호출할 경우에만 문자열 상수 풀에 문자열 저장이 발생위의 이해를 전제로 질문은 아래와 같습니다.[12분 22초]쯤 선생님께서 문자열 상수 풀에서 문자열을 조회할 때,먼저 Runtime Constant Pool 내에 문자열 리터럴을 조회하고, 있으면 바로 반환한다고 하셨는데요.1. 런타임 상수 풀에서만 리터럴을 조회하고 끝나는 절차가 맞는지요? 혹은 "런타임 상수 풀"에 저장된 문자열 리터럴의 심볼릭 참조를 타고 "문자열 상수 풀"의 문자 리터럴 객체를 탐색하는 것까지가 맞는 처리 과정인지요? -> 저는 후자가 맞다고 생각하고 있습니다.2. intern() 호출 시, 런타임 상수 풀 내의 "찾고자 하는 문자열 리터럴의 심볼릭 참조"가 존재하지 않는다면, JVM이 문자열 객체를 생성하여 Heap의 문자열 상수 풀에 저장하나요? 혹은 Heap 영역이지만 문자열 상수 풀이 아닌 영역에 저장되나요? -> 저는 intern() 호출로 생성된 객체는 항상 문자열 상수 풀에 저장되는 걸로 알고 있습니다.3. 그리고 2번 질문과 연관된 질문인데, 수업자료의 예제에서public class Main { public static void main(String[] args) { String s1 = "Hello"; String s2 = "Hello"; System.out.println(s1 == s2); String s3 = new String("World"); String s4 = s3.intern(); System.out.println(s3 == s4); System.out.println("World" == s3); // 1번 System.out.println("World" == s4); // 2번 } }18분 51초 쯤 선생님께서 말씀하시기를 s3.intern()으로 인해 "World" 리터럴이 Runtime constant pool에 생긴다고 하셨는데, Runtime constant Pool은 오직 심볼릭 참조만 가지고 있는거 아닌가요? Runtime constant pool는 클래스 로드 시 정적으로 생성된 심볼릭 참조를 관리할 뿐이고, 동적으로 업데이트 되는건 아니지 않나요?따라서 s3.intern()으로 인해 "World" 리터럴은 Runtime Constant Pool이 아니라 Heap 영역의 문자열 상수 풀에 들어가야하는 것이 아닌지요?마지막으로,[System.out.println("World" == s3); // 1번]여기서 false가 나온 이유는 new로 동적 할당된 "World"은 문자열 상수 풀이 아닌 Heap 영역에 저장되기 때문에s3 참조자는 문자열 상수 풀이 아닌 그 외 Heap 영역의 String instance를 바라보고 있고,s4 참조자는 intern() 함수로 인한 호출로 문자열 상수 풀에 생긴 객체이기 때문에 false가 나온게 아닌지요?제가 잘못 알고 있는 상태에서 잘못된 질문을 길게 한건가 싶어서 죄송스럽네요.늘 좋은 강의 감사합니다!
-
해결됨기초 탄탄! 독하게 시작하는 Java - Part 2 : OOP와 JVM
클래스 로딩 순서에 관해 질문이 있습니다.
10분 24초에 클래스를 로딩하기에 앞서서 검사, 준비, 해결과정을 거친다고 하셨는데 로딩을 한 후 링킹(검사,준비, 해결)과정을 수행하는 것이 아닌가요? 로딩전 링킹과정 후 로딩을 하는 것인가요? 제가 잘못이해하고 있는 것인지 궁금합니다
-
미해결TS/JS 디자인 패턴 with Canvas: 제로초에게 제대로 배우기
리스코프 치환원칙은 반,공변성과 같은 원리인가요?
class Parents { // 좁은 파라미터 method(name: string, test: string) { // 넓은 반환 타입 return { key: "" }; } } class Child extends Parents { // 넓은 파라미터 override method(name: string) { // 좁은 반환 타입 return { key: "", name: "" }; } } 안녕하세요,리스코프 치환원칙을 보니 반,공변성의 원칙과 같이매개변수는 반공변성을 리턴은 공변성을 가지는 것 같은데, T<child> -> T<parents> 개념이 되는 타입의 정의 원칙을 리스코프 치환 원칙이라 하는 것일까요?
-
미해결Readable Code: 읽기 좋은 코드를 작성하는 사고법
DTO 생성과 관련해서 궁금한 게 있습니다!
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. @Transactional public ShelterResponse.FindShelterListDTO findActiveShelterList() { List<Shelter> shelters = shelterRepository.findAllWithAnimalAndLatitude(); List<ShelterResponse.ShelterDTO> shelterDTOS = shelters.stream() .map(shelter -> new ShelterResponse.ShelterDTO( shelter.getId(), shelter.getName(), shelter.getLatitude(), shelter.getLongitude(), shelter.getCareAddr(), shelter.getCareTel())) .collect(Collectors.toList()); return new ShelterResponse.FindShelterListDTO(shelterDTOS); } @Transactional(readOnly = true) public ShelterResponse.FindShelterInfoByIdDTO findShelterInfoById(Long shelterId) { Shelter shelter = shelterRepository.findById(shelterId).orElseThrow( () -> new CustomException(ExceptionCode.SHELTER_NOT_FOUND) ); return new ShelterResponse.FindShelterInfoByIdDTO( shelter.getId(), shelter.getName(), shelter.getLatitude(), shelter.getLongitude(), shelter.getCareAddr(), shelter.getCareTel(), shelter.getAnimalCnt() ); } 위 코드는 유기 동물 보호소 서비스에서 보호소 목록을 가져오고, 보호소의 상세 정보를 가져오는 코드입니다.서비스 레이어에서 컨트룰러 레이어로 응답을 내보낼 때 DTO로 변환해서 보내는데, 데이터양이 많은 엔티티의 경우 위 코드처럼 DTO 빌드 코드가 길어지더라구요.. 그래서, 정보량이 많은 엔티티에 관한 데이터를 DTO로 리턴할 때는 아래와 같이 서비스 레이어에 private 메서드로 추출해서 사용합니다.private ShelterResponse.AnimalDTO createAnimalDTO(Animal animal, List<Long> userLikedAnimalIds) { return new ShelterResponse.AnimalDTO( animal.getId(), animal.getName(), animal.getAge(), animal.getGender(), animal.getSpecialMark(), animal.getKind(), animal.getWeight(), animal.getNeuter(), animal.getProcessState(), animal.getRegion(), animal.getInquiryNum(), getCachedLikeNum(animal.getId()), userLikedAnimalIds.contains(animal.getId()), animal.getProfileURL()); } 여기서 고민이 시작 됐는데, 응답으로 보낼 DTO를 빌드하는 로직을 서비스 레이어에 private 메서드로 추출하는 게 서비스 레이어의 역할 상 괜찮을지 의문이 들더라구요.현업에서는 정보량이 많은 DTO 코드를 빌드하는 부분을 메서드로 따로 추출하는지, 추출한다면 어떻게 처리하는지 궁금합니다!이거를 메서드로 추출하지 않을까도 생각해봤는데, 그러면 메서드의 코드 길이가 너무 길어져서 가독성을 해치는 느낌도 있더라구요.. 또 DTO만 처리하는 클래스를 만들어볼까도 생각했는데 이게 맞나 싶기도 하구요
-
미해결김영한의 실전 자바 - 중급 1편
toString()
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]debug("xx ={} ", str); 에도 내부적으로 toString()이 적용되어서 출력되나요?
-
해결됨김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션
존재하지 않는 ip와 서버가 사용하지 않는 ip의 차이
1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]ai야 999.999.999.999 라는 ip를 사용해서 UnknownHostException 을 받는 경우와 192.168.1.250를 사용해서 ConnectException 을 받는 경우의 차이를 설명해줘
-
미해결김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션
실무 코드스타일 질문
FileReader(FILE_NAME)이렇게 생성하면 시스템의 기본 디폴드 캐릭터셋을 사용한다고했습니다. 그런데 실제로 실무에서 애플리케이션을 만들고 배포하면 어떤 환경에서 실행될지모르기때문에 코드안에 캐릭터셋을 지정해주는 편인가요? FileReader(FILE_NAME, UTF-8)이렇게요개발하는입장에선 당장은 캐릭터셋을 지정안해도되지만 추후에 이 애플리케이션이 실행될 환경을 고려해서 적어주는게 바람직할까요.?
-
해결됨기초 탄탄! 독하게 시작하는 Java - Part 2 : OOP와 JVM
메타데이터의 위치에 대한 질문입니다.
널널한 개발자님. 항상 잘 듣고 있습니다! 좋은 강의 감사합니다. 복습을 하던 도중 잘 이해가 안되는 부분이 있어 질문드립니다.인스턴스의 메타데이터라 함은 강의 내용 중 해시코드, 오브젝트 나이, 락플래그를 말하는 것 같습니다.강의 4분경에서 이런 메타데이터가 Klass word에서 참조하는 Metaspace에 저장되어 있다고 하셨습니다.그리고 강의 6분경 핫스팟 VM 객체 Lock flag슬라이드 보거나, 실제 예제를 실행시켜 나온 결과(23:35)를 보면 Markword에도 해쉬파일과 락플래그가 있는 것으로 보입니다.Metaspace, Markword 둘 다 같은 인스턴스의 해시코드값(+락플래그)을 가지는 건가요? 그러면 Metaspace는 생성된 인스턴스 모두의 메타데이터를 가지는건가요? 새벽에 보느라 머리가 잘 안돌아가네요..긴 글 읽어주셔서 감사합니다!
-
미해결스프링 핵심 원리 - 기본편
MemberApp 코드 실행 오류 문제.
강의 그대로 따라하며 모든 코드를 입력했으나, 강의에서처럼 System.out.println("new member = " + member.getName()); System.out.println("find Member = " + findMember.getName());이를 출력했을 때 값이 정상적으로 안나옵니다.찾아보니 gradle 파일 내부 문제가 있는듯 한데, 뭐가 문제인지 모르겠습니다. 코드 전부를 첨부합니다.. 도와주세요...!plugins { id 'java' id 'org.springframework.boot' version '3.4.0' id 'io.spring.dependency-management' version '1.1.6' } group = 'hello' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter' testImplementation ('org.springframework.boot:spring-boot-starter-test'){ exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() } package hello.core; import hello.core.member.Grade; import hello.core.member.Member; import hello.core.member.MemberService; import hello.core.member.MemberServiceImpl; public class MemberApp { public static void main(String[] args) { MemberService memberService = new MemberServiceImpl(); Member member = new Member(1L, "memberA", Grade.VIP); memberService.join(member); Member findMember = memberService.findMember(1L); System.out.println("new member = " + member.getName()); System.out.println("find Member = " + findMember.getName()); } }
-
해결됨스프링 핵심 원리 - 기본편
@Configuration
[질문 내용]컴포넌트 스캔을 사용하면 @Configuration이 붙은 설정 정보도 자동으로 등록된다 하였는데 AutoAppConfig 클래스에 있는 @Configuration은 왜 설정해 두신건지 궁금합니다.
-
미해결스프링 핵심 원리 - 기본편
destroyMethod="" 빈공백을 사용하면?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]8장 빈 생명주기 콜백 의 빈 등록 초기화, 소멸 메서드 관련 질문입니다.마지막 종료 메서드 추론 부분에서 "추론 기능을 사용하기 싫으면 destroyMethod="" 처럼 빈 공백을 지정하면 된다"라고 말씀 하셨습니다.그런데 추론 기능을 사용하기 싫으면 destroyMethod에 close나 shutdown이 아닌 내가 지정한 메소드 이름을 입력해야 하는 거 아닌가요?빈 공백을 지정하면 소멸 메서드를 아예 지정하지 않아서 실행도 되지 않는 것 같은데 저게 무슨 말인지 이해가 안갑니다.답변 미리 감사합니다.(destroyMethod의 디폴트 값이 close와 shutdown이어서 @Bean에 destroyMethod를 적지 않으면 자동으로 close와 shutdown 메소드를 실행하는 것까진 이해했습니다.)