Spring 3.1 환경에 있는 프로젝트를 진행하던 중 생성자주입 방식을 사용하자 에러가 났다. 대부분의 코드에서 필드주입을 대신하여 사용하고 있었고, 생성자주입 대신 필드주입을 사용하니 에러가 해결되었다. 왜 이러한 에러가 났는지 조사해보았다.
현재 spring 3.1인 환경에서는
의 문제가 있다.
특히 프록시 되는 객체에 default 생성자가 없는 경우 생성자 주입 방식을 사용하면 에러[1]가 발생한다.
spring 4 이상의 버전에서는 문제가 해결되었다고 한다. 자세한 내용은 참고
(참고: https://code-lab1.tistory.com/193 ),
AOP에 등록되지 않아 프록시가 만들어지지 않았기 때문이다. 혹은 인터페이스가 존재하여 CGLIB 대신 jdk-proxy가 활용되는 경우이다.
(실제로 해당 객체에 @Transactional 키워드를 붙이니 에러가 발생한다.)
※모든 스프링 빈이 프록싱되는 것은 아니다.
(참고: 문제해결에 도움을 받은 문서)
추가하면 생성자 주입을 활용할 수 있다. 하지만 아래와 같은 이유로 default 생성자 + 생성자 주입 대신 기존의 방식대로 필드 주입을 사용하기로 결정했다.
[1] 발생한 에러
| org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'XXXController' defined in ~\XXXController.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class XXXController]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:638) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:462) at
| --- |