【问题标题】:Cannot Declare Beans inside ApplicationContext.xml无法在 ApplicationContext.xml 中声明 Bean
【发布时间】:2015-07-17 14:39:36
【问题描述】:

答对的人将获得奖励 我的实现如下:

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;
    }
}

【问题讨论】:

  • 当您发布代码时,请按原样发布代码,您的代码与堆栈跟踪中告知的内容不匹配。您正在构造函数中创建JdbcTemplate,此时数据源仍为空。改用构造函数注入。
  • 截至目前未使用构造函数注入,如果我使用它,则会在构造函数映射上显示错误,要求我们定义我们尝试传递的成员的索引/类型/名称跨度>
  • 只有一个不正确的构造函数参数(或者你做错了事)。这也是必需的,因此为此设置一个设置器真的没有意义......
  • 我只有 setter 方法。我的编码中没有构造函数。堆栈跟踪说它是构造函数
  • @M.Deinum 你想让我展示 NextShipmentDaoImpl

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


【解决方案1】:

基于 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....

}

【讨论】:

【解决方案2】:

堆栈跟踪说:

  • 您正确地将nextShipmentDAO 自动连接到loginController
  • dataSource 属性为null 是NextShipmentDAOImpl bean
  • 并且异常发生在JdbcTemplate初始化中

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

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

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

不得在创建时使用注入的字段,因为那时它还没有被注入。在设置所有属性后,您应该使用 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>

【讨论】:

  • 我的所有 xml 文件都已加载。我会检查并回复你。
  • 你认为混合注解和手动定义一个bean的数据源配置可能会导致错误
  • @MSIbrahim Spring 明确允许混合注释、Java 配置和 XML 文件。如果您知道使用了哪些配置文件以及它们是如何使用的,那么它就很有意义。在这里,board-dao.xml 是什么?
  • 我已经将特定于 dao 的 bean 分离到 board-dao.xml,类似 board-servlet.xml board-service.xml board-security.xml
  • 我只在 spring2.5.6 和 spring 4.0.1 中的 spring3.2.4 中遇到过这种情况我没有遇到过 bean 创建异常是否应该使用 spring 4.0.1 jar 文件..
【解决方案3】:

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 问题就这样解决了。

【讨论】:

    猜你喜欢
    • 2012-11-27
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    相关资源
    最近更新 更多