问题
Hello everyone I'm getting an exception while develeping a web application with spring mvc and hibernate, the problem is that spring don't know my beans Controller
@Autowired
public PersonneMetierImpl personneMetier;
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(Locale locale, Model model) {
personneMetier.ajouterPersonne(new Personne("azrou", "zakaria.bariki@gmail.com", "bariki", "zakaria", "0641057217"));
return "test";
}
DAO classe
@Repository
public class PersonneDaoImpl implements IPersonneDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public void ajouterPersonne(Personne personne) {
if(sessionFactory == null)
System.out.println("aaaa");
try{
sessionFactory.getCurrentSession().save(personne);
}catch(Exception e){
e.printStackTrace();
}
}
Service class Service public class PersonneMetierImpl implements IPersonneMetier{ @Autowired private PersonneDaoImpl personneDao;
@Override
@Transactional
public void ajouterPersonne(Personne personne) {
personneDao.ajouterPersonne(personne);
}
Servlet-Context file
<beans:bean id="datasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url"
value="jdbc:mysql://localhost:3306/gestion_bp" />
<beans:property name="username" value="root" />
<beans:property name="password" value="" />
</beans:bean>
<beans:bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="datasource" />
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.show_sql">true</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<context:component-scan base-package="com.sqli.bap" />
<beans:bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="personneDao" class="com.sqli.bap.daoImpl.PersonneDaoImpl"/>
<beans:bean id="personneMetier" class="com.sqli.bap.metierImpl.PersonneMetierImpl"/>
Exception
ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.sqli.bap.metierImpl.PersonneMetierImpl com.sqli.bap.HomeController.personneMetier; nested exception is java.lang.IllegalArgumentException: Can not set com.sqli.bap.metierImpl.PersonneMetierImpl field com.sqli.bap.HomeController.personneMetier to com.sun.proxy.$Proxy16
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1122)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
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.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5253)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5543)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1574)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1564)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.sqli.bap.metierImpl.PersonneMetierImpl com.sqli.bap.HomeController.personneMetier; nested exception is java.lang.IllegalArgumentException: Can not set com.sqli.bap.metierImpl.PersonneMetierImpl field com.sqli.bap.HomeController.personneMetier to com.sun.proxy.$Proxy16
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 29 more
Caused by: java.lang.IllegalArgumentException: Can not set com.sqli.bap.metierImpl.PersonneMetierImpl field com.sqli.bap.HomeController.personneMetier to com.sun.proxy.$Proxy16
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:510)
... 31 more
Can anyone tell me what's can I do to resolve the problem please Thank you a lot
回答1:
You need to change your controller - replace the line
public PersonneMetierImpl personneMetier;
with
public IPersonneMetier personneMetier;
(that is, use interface instead of an implementation).
In some cases (including yours) Spring doesn't use a bean (PersonneMetierImpl) as-is, but wraps it in a proxy. In this case it is a JDK dynamic proxy, which cannot be cast to PersonneMetierImpl, but only to IPersonneMetier (JDK proxies are interface-based). And that is the reason why Spring cannot autowire field PersonneMetierImpl personneMetier.
Oh, and for the same reason (and also because that's what interfaces are for) you should change PersonneMetierImpl class - replace private PersonneDaoImpl personneDao with private IPersonneDao personneDao.
回答2:
The controller is not a true representation of the class but rather a proxy generated by Spring. This will implement all the interfaces of the class however so you could use
@Autowired
public IPersonneDao personneMetier;
instead of
@Autowired
public PersonneMetierImpl personneMetier;
回答3:
This error can also appear as a bug for IntelliJ IDEA users. Eclipse and java for VS Code do not produce this problem.
来源:https://stackoverflow.com/questions/33792366/spring-cant-create-beans