无法在ApplicationContext.xml中声明Bean

时间:2015-05-07 07:00:55

标签: java spring spring-mvc spring-security spring-data

任何回答正确的人都将获得奖励 我的实施如下:

NextShipmentDaoImpl.java

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

LoginController.java

@Controller  
public class LoginController {  

      @Autowired
      private NextShipmentDao nextShipmentDao;

      public void setNextShipmentDao(NextShipmentDao nextShipmentDao) {
        this.nextShipmentDao = nextShipmentDao;
     }

在创建上述所需的bean时:

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>

的applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
 xmlns:context="http://www.springframework.org/schema/context"  
 xmlns:tx="http://www.springframework.org/schema/tx"  
 xsi:schemaLocation=" 
http://www.springframework.org/schema/beans  
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
http://www.springframework.org/schema/context  
http://www.springframework.org/schema/context/spring-context-3.0.xsd  
http://www.springframework.org/schema/tx  
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
<property name="driverClassName" value="com.mysql.jdbc.Driver" />  
<property name="url" value="jdbc:mysql://localhost:3306/board" />  
<property name="username" value="root" />  
<property name="password" value="root" />  
</bean>

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>

 <security:http auto-config="true" >  
 <security:intercept-url pattern="/index*" access="ROLE_USER" />  
 <security:form-login login-page="/login.htm" default-target-url="/index.htm"  
  authentication-failure-url="/loginerror.htm" />  
 <security:logout logout-success-url="/logout.htm" />  
 </security:http> 


<context:component-scan base-package="com.ibrahim.controller,com.ibrahim.domain,com.ibrahim.dao" />  

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
<property name="viewClass"  value="org.springframework.web.servlet.view.JstlView" />  
<property name="prefix" value="/WEB-INF/views/" />  
<property name="suffix" value=".jsp" />  
</bean>
</beans>

一切正常。但是当我尝试创建一个bean时显示错误

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.ibrahim.dao.NextShipmentDao com.ibrahim.controller.LoginController.nextShipmentDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nextShipmentDao' defined in ServletContext resource [/WEB-INF/board-dao.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    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:628)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4728)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5166)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    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: private com.ibrahim.dao.NextShipmentDao com.ibrahim.controller.LoginController.nextShipmentDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nextShipmentDao' defined in ServletContext resource [/WEB-INF/board-dao.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    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)
    ... 22 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nextShipmentDao' defined in ServletContext resource [/WEB-INF/board-dao.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1007)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:953)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    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.findAutowireCandidates(DefaultListableBeanFactory.java:912)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:855)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
    ... 24 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1000)
    ... 35 more
Caused by: java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.jdbc.support.JdbcAccessor.afterPropertiesSet(JdbcAccessor.java:134)
    at org.springframework.jdbc.core.JdbcTemplate.<init>(JdbcTemplate.java:165)
    at com.ibrahim.dao.NextShipmentDaoImpl.<init>(NextShipmentDaoImpl.java:28)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
    ... 37 more

May 07, 2015 12:21:48 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
May 07, 2015 12:21:48 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/13.1SecuringUrlAcces] startup failed due to previous errors
May 07, 2015 12:21:48 PM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
May 07, 2015 12:21:48 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
May 07, 2015 12:21:48 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
May 07, 2015 12:21:48 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 12402 ms

这是我的NextShipmentDaoImpl.java

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    JdbcTemplate jdbcTemplate= new JdbcTemplate(dataSource);

    @Override
    public List<NextShipment> display() {

        String sql = "SELECT * FROM NEXTSHIPMENT";

        List<NextShipment> shipments = new ArrayList<NextShipment>();
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
        for (Map row : rows) {
            NextShipment shipment = new NextShipment();
            shipment.setOid((String) row.get("OID"));
            shipment.setAddress((String) row.get("ADDRESS"));
            shipment.setPack_Date((Date) row.get("PACK_DATE"));
            shipment.setIsAvailable((Boolean) row.get("ISAVAILABLE"));
            shipment.setAssignShipper((String) row.get("ASSIGNSHIPPER"));
            shipment.setInTransit((Boolean) row.get("InTransit"));
            shipments.add(shipment);
        }
        return shipments;
    }
}

3 个答案:

答案 0 :(得分:0)

基于XML的配置的时代结束了。

我强烈建议您使用Annotated Configuration

这样的事情:

@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan(basePackages = "com.myapp.*")
public class AppConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    public DataSource myDataSource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName("<full.driver.class.name>");
        dataSource.setUrl("url");
        dataSource.setUsername("dit");
        dataSource.setPassword("pass");

        return dataSource;
    }

    [...] other Beans like TransactionManager....

}

答案 1 :(得分:0)

stacktrace说:

  • 您在nextShipmentDAO
  • 中正确地自动装配了loginController
  • dataSource属性为null是NextShipmentDAOImpl bean
  • 并在JdbcTemplate初始化
  • 中发生异常

NextShipmentDAOImpl给出了原因:您正确地注入了数据源,但在构造时初始化JdbcTemplate。所以这是发生的事情:

  • jvm创建一个NextShipmentDaoImpl对象
  • jvm初始化对象的所有字段,包括jdbcTemplate
  • spring设置数据源字段......太晚了!

[@ M.Deinum在评论中已经注意到了,但我没有给予足够的重视]

永远不会在创建时使用注入的字段,因为那时它还没有被注入。在设置了所有属性后,您应该使用spring调用的初始化方法:

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    JdbcTemplate jdbcTemplate;

    void init(void) {
        jdbcTemplate = new JdbcTemplate(dataSource);
    }

并以这种方式声明bean:

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl" 
    init-method="init">
<property name="dataSource" ref="dataSource"></property>
</bean>

答案 2 :(得分:0)

NextShipmentDaoImpl.java看起来像这样

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    JdbcTemplate jdbcTemplate;

    public NextShipmentDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

在上面的代码行中,我在其实现函数本身中声明了JdbcTemplate。在哪里使用。

我宣布的相关bean是:

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>

LoginController保持不变:

@Controller  
public class LoginController {  

     @Autowired
      private NextShipmentDao nextShipmentDao;

       public void setNextShipmentDao(NextShipmentDao nextShipmentDao) {
        this.nextShipmentDao = nextShipmentDao;
     }

我把弹簧和弹簧安全罐从3.2.4改为3.2.7 问题以这种方式得到了解决。