无法在ApplicationContext.xml中声明Bean

时间:2022-09-11 16:44:55

Whoever answers correct will be rewarded My Implementation is as follows:

谁回答正确将得到奖励我的实施如下:

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

While Creating the required above bean like this:

在创建所需的上述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>

Everything works fine. But when I try to create a bean This shows the error

一切正常。但是当我尝试创建一个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

Here's My NextShipmentDaoImpl.java

这是我的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 个解决方案

#1


The times of the XML-based configuration are over.

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

I strongly recommend you to use Annotated Configuration

我强烈建议您使用带注释的配置

Something like this:

像这样的东西:

@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


The stacktrace says :

堆栈跟踪说:

  • you correctly autowire nextShipmentDAO in loginController
  • 你正确地在loginController中自动装配nextShipmentDAO

  • but dataSource property is null is the NextShipmentDAOImpl bean
  • 但dataSource属性为null是NextShipmentDAOImpl bean

  • and the exception occurs in JdbcTemplate initialization
  • 并且在JdbcTemplate初始化中发生异常

The NextShipmentDAOImpl gives the cause : you correctly inject the datasource, but initialize the JdbcTemplate at construction time. So here is what happens :

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

  • jvm creates a NextShipmentDaoImpl object
  • jvm创建一个NextShipmentDaoImpl对象

  • jvm initializes all fields of the object including jdbcTemplate
  • jvm初始化对象的所有字段,包括jdbcTemplate

  • spring sets the datasource field ... too late !
  • spring设置数据源字段......太晚了!

[It had been noted in comments by @M.Deinum, but I did not give it enough attention]

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

You shall never use an injected field at creation time, because at that moment it has not been injected. You should instead use an initialization method called by spring after all properties have been set :

你永远不会在创建时使用注入的场,因为那时它还没有被注入。在设置了所有属性之后,您应该使用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);
    }

and declare the bean that way :

并以这种方式声明bean:

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

#3


NextShipmentDaoImpl.java looks like this

NextShipmentDaoImpl.java看起来像这样

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    JdbcTemplate jdbcTemplate;

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

In the above lines of code I had declared JdbcTemplate inside its implementation function itself. Where it is used.

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

And the relevant bean I had declared is:

我宣布的相关bean是:

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

LoginController remains the same:

LoginController保持不变:

@Controller  
public class LoginController {  

     @Autowired
      private NextShipmentDao nextShipmentDao;

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

I had shifted my spring and spring security jars from 3.2.4 to 3.2.7 Problem got solved in this manner.

我把我的弹簧和弹簧安全罐从3.2.4转移到3.2.7问题以这种方式解决了。

#1


The times of the XML-based configuration are over.

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

I strongly recommend you to use Annotated Configuration

我强烈建议您使用带注释的配置

Something like this:

像这样的东西:

@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


The stacktrace says :

堆栈跟踪说:

  • you correctly autowire nextShipmentDAO in loginController
  • 你正确地在loginController中自动装配nextShipmentDAO

  • but dataSource property is null is the NextShipmentDAOImpl bean
  • 但dataSource属性为null是NextShipmentDAOImpl bean

  • and the exception occurs in JdbcTemplate initialization
  • 并且在JdbcTemplate初始化中发生异常

The NextShipmentDAOImpl gives the cause : you correctly inject the datasource, but initialize the JdbcTemplate at construction time. So here is what happens :

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

  • jvm creates a NextShipmentDaoImpl object
  • jvm创建一个NextShipmentDaoImpl对象

  • jvm initializes all fields of the object including jdbcTemplate
  • jvm初始化对象的所有字段,包括jdbcTemplate

  • spring sets the datasource field ... too late !
  • spring设置数据源字段......太晚了!

[It had been noted in comments by @M.Deinum, but I did not give it enough attention]

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

You shall never use an injected field at creation time, because at that moment it has not been injected. You should instead use an initialization method called by spring after all properties have been set :

你永远不会在创建时使用注入的场,因为那时它还没有被注入。在设置了所有属性之后,您应该使用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);
    }

and declare the bean that way :

并以这种方式声明bean:

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

#3


NextShipmentDaoImpl.java looks like this

NextShipmentDaoImpl.java看起来像这样

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    JdbcTemplate jdbcTemplate;

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

In the above lines of code I had declared JdbcTemplate inside its implementation function itself. Where it is used.

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

And the relevant bean I had declared is:

我宣布的相关bean是:

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

LoginController remains the same:

LoginController保持不变:

@Controller  
public class LoginController {  

     @Autowired
      private NextShipmentDao nextShipmentDao;

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

I had shifted my spring and spring security jars from 3.2.4 to 3.2.7 Problem got solved in this manner.

我把我的弹簧和弹簧安全罐从3.2.4转移到3.2.7问题以这种方式解决了。