2013-03-05 3 views
27

Im использования Spring Social в моем приложении:суперкласса не имеет нулевые конструкторов, но аргументы не были даны

<spring.framework.version>3.2.0.RELEASE</spring.framework.version> 
<hibernate.version>4.1.9.Final</hibernate.version> 
<commons-dbcp.version>1.4</commons-dbcp.version> 
<org.springframework.social-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social-version> 
<org.springframework.social.facebook-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social.facebook-version> 
<org.springframework-version>3.2.1.RELEASE</org.springframework-version> 
<org.springframework.security.crypto-version>3.1.3.RELEASE</org.springframework.security.crypto-version> 

Когда я применяю

private final Facebook facebook; 

@Inject 
public SearchController(Facebook facebook) { 
    this.facebook = facebook; 
} 

К моему HomeController:

@Controller 
public class HomeController { 


    private final Facebook facebook; 

    @Inject 
    public HomeController(Facebook facebook) { 
     this.facebook = facebook; 
    } 

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class); 

    /** 
    * Simply selects the home view to render by returning its name. 
    */ 
    @RequestMapping(value = "/", method = RequestMethod.GET) 
    public String home(Model model) { 
     return "home"; 
    } 

} 

инъекционные работы, такие как намеренные, и я могу получить информацию от facebook. Однако, когда я применяю его к одному из моих других Cotrollers как этот

@Controller 
@Transactional 
@RequestMapping(value = "/search") 
public class SearchController { 

    private static final Logger logger = LoggerFactory.getLogger(SearchController.class); 

    private final Facebook facebook; 

    @Inject 
    public SearchController(Facebook facebook) { 
     this.facebook = facebook; 
    } 

    @PersistenceContext 
    private EntityManager entityManager; 

    ... 

Я получаю эту ошибку:

mar 05, 2013 12:46:36 EM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/project] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchController' defined in file [C:\Users\Nilsi\Downloads\springsource\vfabric-tc-server-developer-2.7.2.RELEASE\base-instance\wtpwebapps\course_info\WEB-INF\classes\com\courseinfo\project\controller\SearchController.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.courseinfo.project.controller.SearchController]: 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] with root cause 
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given 
    at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721) 
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499) 
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) 
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) 
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) 
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) 
    at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285) 
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) 
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:412) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1492) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117) 
    at org.springframework.web.method.HandlerMethod.createWithResolvedBean(HandlerMethod.java:202) 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:233) 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:55) 
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297) 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1091) 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1076) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:896) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:920) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:827) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:722) 

Я предполагаю, что я не могу вводить фейсбук к контроллеру с аннотацией @ транзакционный? Я googled вокруг, но наклоняю найти любое решение к этому.

+0

Он работает, если вы используете инъекцию на основе свойств? –

+0

Ничего себе, это сработало! если вы поместите его в качестве ответа, я буду отмечать его как правильное. Я просто удалил конструктор и изменил на это: @Inject частный Facebook facebook; Протестировано до этого, но не могло заставить его работать, потому что переменная изначально была окончательной. (Был окончательным в примере примера Springs, из которого я получил его). – nilsi

ответ

53

У CGlib есть одно важное ограничение: целевой класс должен предоставить конструктор по умолчанию.

Если вы используете инъекцию на основе свойств вместо инъекции на основе конструктора, проблема исчезнет.

+40

Развернувшись на этом ответе: это могло бы сработать через конструктор-инъекцию (что предпочтительнее), если бы вы не добавили '@ Transactional' в контроллер. После того, как вы добавили '@ Transactional', AOP запускается, а прокси-сервер должен быть создан. CGLib нужен конструктор по умолчанию. Другое решение - настроить Spring-транзакции для использования AspectJ вместо прокси. Для этого требуется немного больше настроек, но разрешить транзакции для класса без конструктора по умолчанию. –

+3

Это очень хороший комментарий! Я думаю, что это нужно добавить к ответу. –

+6

До весны 4 для прокси-классов на основе CGLIB требуется конструктор по умолчанию. И это не ограничение библиотеки CGLIB, а сама Весна. К счастью, с весны 4 это уже не проблема. Прокси-классы на основе CGLIB больше не требуют конструктора по умолчанию. См. Эту статью: http://blog.codeleak.pl/2014/07/spring-4-cglib-based-proxy-classes-with-no-default-ctor.html –

0

Я только что создал пустой конструктор по умолчанию, чтобы справиться с этим.