작성
·
1.5K
0
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오) 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예
[질문 내용]
모든 코드를 작성하고 빨간 줄은 없는데 실행하면 다음과 같이 뜹니다..다른 분의 질문을 참고해봤는데도 동일합니다..
참고한 링크입니다 (https://www.inflearn.com/questions/674179, https://www.inflearn.com/questions/674651)
답변 3
0
MemoryMemberRepsitory클래스 위에 @Repository를 지우고 실행해보시겠어요?
@Bean
public MemberService memberService() {
return new MemberService((MemoryMemberRepository) memberRepository());
}
SpringConfig 이 코드도 강의랑 동일하게 변경해주세요.
그렇게 해보았는데 여전히 같은 오류가 뜨는 것 같습니다..
필드만 보고, 생성자를 못봤네요 ㅎㅎ;
public MemberService(MemoryMemberRepository memberRepository) {
this.memberRepository=memberRepository;
}
(MemoryMemberRepository memberRepository)
이 부분을
MemoryMemberRepository -> MemberRepository로 바꿔주세요
변경해야 하는 이유를 설명드리면,
구체적인 클래스인 MemoryMemberRepository에 의존하지 않고,
MemberRepository 인터페이스를 구현한 다양한 xxxMemberRepository를 주입 받으려면 생성자의 파라미터는 인터페이스가 와야됩니다^^
해당부분을 찾아 수정하였더니 빨간줄 오류는 사라졌습니다!
그런데 실행시 또 다른 오류가 떠서요............... 공유드라이브로 파일 첨부합니다..
애써주시는데 감사하고.. 죄송하네요..ㅎ
https://drive.google.com/file/d/1i6BLwwoF4EIEjxTxoftPFMswUv9l0znl/view?usp=sharing
오류는 다음과 같습니다
2022-11-09 21:29:48.195 INFO 17656 --- [ main] c01.c01spring.C01SpringApplication : Starting C01SpringApplication using Java 16.0.2 on DESKTOP-K3VMF2D with PID 17656 (C:\Spring\c01-spring\c01-spring\out\production\classes started by 영서 in C:\Spring\c01-spring\c01-spring)
2022-11-09 21:29:48.205 INFO 17656 --- [ main] c01.c01spring.C01SpringApplication : No active profile set, falling back to 1 default profile: "default"
2022-11-09 21:29:50.274 WARN 17656 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'memberService' defined in class path resource [c01/c01spring/SpringConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=springConfig; factoryMethodName=memberService; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [c01/c01spring/SpringConfig.class]] for bean 'memberService': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=c01SpringApplication.SpringConfig; factoryMethodName=memberService; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [c01/c01spring/C01SpringApplication$SpringConfig.class]] bound.
2022-11-09 21:29:50.305 INFO 17656 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-11-09 21:29:50.423 ERROR 17656 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'memberService', defined in class path resource [c01/c01spring/SpringConfig.class], could not be registered. A bean with that name has already been defined in class path resource [c01/c01spring/C01SpringApplication$SpringConfig.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
Process finished with exit code 1
오류 해결했습니다!!!!!! 오류 잘 읽어보고 C01SpringApplication 클래스에서 @Bean을 삭제해주었더니 오류 없이 실행됩니다 ㅎㅎ
감사합니다 ㅎㅎ
혹시 ... 오류가 해결된 이유 아신다면 댓글 부탁드립니다..!
@SpringBootApplication
public class C01SpringApplication {
public static void main(String[] args) {
SpringApplication.run(C01SpringApplication.class, args);
}
@Configuration
public static class SpringConfig {
private final DataSource dataSource;
public SpringConfig(DataSource dataSource){
this.dataSource=dataSource;
}
@Bean
public MemberService memberService() {
return new MemberService((MemoryMemberRepository) memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new JdbcMemberRepository(dataSource);
}
}
}
@Configuration
public class SpringConfig {
private final DataSource dataSource;
public SpringConfig(DataSource dataSource){
this.dataSource=dataSource;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new JdbcMemberRepository(dataSource);
}
}
스프링이 관리하는 객체로 등록을 두번하는 과정이 발생하여 빈 정의 중복 오류가 발생한 것 같네요.
0
Caused by: java.lang.ClassCastException: class c01.c01spring.repository.JdbcMemberRepository
cannot be cast to class c01.c01spring.repository.MemoryMemberRepository
(c01.c01spring.repository.JdbcMemberRepository and c01.c01spring.repository.MemoryMemberRepository are in unnamed module of loader 'app')
memberController 쪽 문제라기 보다는
Repository 형변환 관련 문제가 있는 것 같습니다.
MemberService 클래스와 SpringConfig 클래스를 확인해보셔야 할 것 같아요.
확인해보시고 해결이 안될 경우
MeberService, SpringConfig, MemberRepository, MemoryMemberRepository, JdbcMemberRepository 클래스 코드도 복사하여 댓글로 남겨주세요 ^^
일단 두 클래스 강의자료 보면서 수정해보았습니다.. 그래도 같은 오류가 뜨네요,, 코드 첨부하겠습니다!
package c01.c01spring.service;
import c01.c01spring.domain.Member;
import c01.c01spring.repository.MemberRepository;
import c01.c01spring.repository.MemoryMemberRepository;
import java.util.List;
import java.util.Optional;
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemoryMemberRepository memberRepository) {
this.memberRepository=memberRepository;
}
/**
* 회원가입
*/
public Long join(Member member) {
//같은 이름이 있는 중복 회원 X
validateDuplicateMember(member); //중복 회원 검증
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
/**
* 전체 회원 조회
*/
public List<Member> findMembers() { //변수명을 서비스파트에서는 좀더 비즈니스적으로
return memberRepository.findAll();
}
public Optional<Member> findOne(Long memberId) {
return memberRepository.findById(memberId);
}
}
package c01.c01spring.service;
import c01.c01spring.repository.JdbcMemberRepository;
import c01.c01spring.repository.MemberRepository;
import c01.c01spring.repository.MemoryMemberRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SpringConfig {
private final DataSource dataSource;
public SpringConfig(DataSource dataSource){
this.dataSource=dataSource;
}
@Bean
public MemberService memberService() {
return new MemberService((MemoryMemberRepository) memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new JdbcMemberRepository(dataSource);
}
}
package c01.c01spring.repository;
import c01.c01spring.domain.Member;
import java.util.List;
import java.util.Optional;
public interface MemberRepository {
Member save(Member member); //저장
Optional<Member> findById(Long id); //찾아오기
Optional<Member> findByName(String name); //찾아오기
List<Member> findAll(); //모든회원리스트반환
}
package c01.c01spring.repository;
import c01.c01spring.domain.Member;
import org.springframework.stereotype.Repository;
import java.util.*;
@Repository
public class MemoryMemberRepository implements MemberRepository {
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L; //key값 생성
@Override
public Member save(Member member) {
member.setId(++sequence);
store.put(member.getId(), member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
return Optional.ofNullable(store.get(id)); //null이어도 감쌀 수 있음
}
@Override
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
@Override
public Optional<Member> findByName(String name) {
return store.values().stream()
.filter(member -> member.getName().equals(name)) //람다 사용, 이름이 같은지 확인
.findAny();
}
public void clearStore() {
store.clear();
}
}
package c01.c01spring.repository;
import c01.c01spring.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; //DB에 붙으려면 필요함
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(); //DB에 메모리가 날라감
rs = pstmt.getGeneratedKeys(); //DB에서 ID반환
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); //release
}
}
@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);
}
}
0
2022-11-09 20:28:53.742 INFO 7416 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-11-09 20:28:53.829 ERROR 7416 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberController' defined in file [C:\Spring\c01-spring\c01-spring\out\production\classes\c01\c01spring\controller\MemberController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'memberService' defined in class path resource [c01/c01spring/service/SpringConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [c01.c01spring.service.MemberService]: Factory method 'memberService' threw exception; nested exception is java.lang.ClassCastException: class c01.c01spring.repository.JdbcMemberRepository cannot be cast to class c01.c01spring.repository.MemoryMemberRepository (c01.c01spring.repository.JdbcMemberRepository and c01.c01spring.repository.MemoryMemberRepository are in unnamed module of loader 'app')
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.23.jar:5.3.23]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.23.jar:5.3.23]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.4.jar:2.7.4]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.4.jar:2.7.4]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.4.jar:2.7.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.4.jar:2.7.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.4.jar:2.7.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.4.jar:2.7.4]
at c01.c01spring.C01SpringApplication.main(C01SpringApplication.java:10) ~[classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'memberService' defined in class path resource [c01/c01spring/service/SpringConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [c01.c01spring.service.MemberService]: Factory method 'memberService' threw exception; nested exception is java.lang.ClassCastException: class c01.c01spring.repository.JdbcMemberRepository cannot be cast to class c01.c01spring.repository.MemoryMemberRepository (c01.c01spring.repository.JdbcMemberRepository and c01.c01spring.repository.MemoryMemberRepository are in unnamed module of loader 'app')
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.23.jar:5.3.23]
... 19 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [c01.c01spring.service.MemberService]: Factory method 'memberService' threw exception; nested exception is java.lang.ClassCastException: class c01.c01spring.repository.JdbcMemberRepository cannot be cast to class c01.c01spring.repository.MemoryMemberRepository (c01.c01spring.repository.JdbcMemberRepository and c01.c01spring.repository.MemoryMemberRepository are in unnamed module of loader 'app')
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.23.jar:5.3.23]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.23.jar:5.3.23]
... 33 common frames omitted
Caused by: java.lang.ClassCastException: class c01.c01spring.repository.JdbcMemberRepository cannot be cast to class c01.c01spring.repository.MemoryMemberRepository (c01.c01spring.repository.JdbcMemberRepository and c01.c01spring.repository.MemoryMemberRepository are in unnamed module of loader 'app')
at c01.c01spring.service.SpringConfig.memberService(SpringConfig.java:22) ~[classes/:na]
at c01.c01spring.service.SpringConfig$$EnhancerBySpringCGLIB$$5de793ea.CGLIB$memberService$0(<generated>) ~[classes/:na]
at c01.c01spring.service.SpringConfig$$EnhancerBySpringCGLIB$$5de793ea$$FastClassBySpringCGLIB$$426b9941.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.23.jar:5.3.23]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.23.jar:5.3.23]
at c01.c01spring.service.SpringConfig$$EnhancerBySpringCGLIB$$5de793ea.memberService(<generated>) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.23.jar:5.3.23]
... 34 common frames omitted
Process finished with exit code 1
여기있습니다!