Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Springbean已创建但未自动连接_Java_Spring_Testng_Spring Jdbc - Fatal编程技术网

Java Springbean已创建但未自动连接

Java Springbean已创建但未自动连接,java,spring,testng,spring-jdbc,Java,Spring,Testng,Spring Jdbc,我试图在春季为DAO类运行TestNG测试。但是,尽管有注释,数据源引用并不是自动连接的。以下是测试的一部分: @ContextConfiguration(locations={"classpath:WEB-INF/servlet-context.xml"}) public class ToDoDaoImplTest extends AbstractTestNGSpringContextTests { @Autowired // Construction of this obj

我试图在春季为DAO类运行TestNG测试。但是,尽管有注释,数据源引用并不是自动连接的。以下是测试的一部分:

@ContextConfiguration(locations={"classpath:WEB-INF/servlet-context.xml"})
public class ToDoDaoImplTest extends AbstractTestNGSpringContextTests {

    @Autowired
    // Construction of this object fails
    private ToDoItemDaoImpl toDoDao;
}
以下是我的Spring配置:

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

<!-- DataSource to be injected -->
<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:test" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
    <jdbc:script location="classpath:db.create.sql" />
</jdbc:initialize-database>

<context:component-scan base-package="org.myapp"/>
以下是错误的跟踪:

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.myapp.dao.ToDoItemDaoImpl]: 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:1004)
    ... 50 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 org.springframework.jdbc.core.simple.AbstractJdbcInsert.<init>(AbstractJdbcInsert.java:97)
    at org.springframework.jdbc.core.simple.SimpleJdbcInsert.<init>(SimpleJdbcInsert.java:60)
    at org.myapp.dao.ToDoItemDaoImpl.<init>(ToDoItemDaoImpl.java:33)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
    ... 52 more
null
这让我很困惑。数据源对象已创建,但未自动连接到Spring管理的对象中。我做错了什么?

问题就在这里

public ToDoItemDaoImpl() {
    // dataSource is null here
    insert = new SimpleJdbcInsert(dataSource).withTableName("toDoItem").usingGeneratedKeyColumns("id");
}
Spring只能在创建对象后自动关联字段。这在构造函数完成后发生

Spring将使用反射,例如
Class.forName(yourClass).newInstance()
,来创建bean,然后再次使用反射来设置每个属性

但是,在构造函数中,字段仍然是
null
,因为这是引用类型的所有未初始化字段的默认值

一种解决方案是将构造函数保留为空并添加带注释的方法

@PostConstruct
public void init() {
    insert = new SimpleJdbcInsert(dataSource).withTableName("toDoItem").usingGeneratedKeyColumns("id");
}

另一个解决方案是在
setDataSource()
方法中添加该初始化。

除了上面Sotirios建议的方法外,还可以使用Spring的构造函数args依赖项注入来初始化数据源。因此,您可以将构造函数修改为:

public ToDoItemDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
        insert = new SimpleJdbcInsert(dataSource).withTableName("toDoItem").usingGeneratedKeyColumns("id");
    }
然后还需要在bean配置文件中添加以下行:

<bean id="toDoItemDaoImpl" class="mypackage.ToDoItemDaoImpl">
    <constructor-arg ref="dataSource"/>
</bean> 

这个“@Autowired is null”问题是个金矿,不是吗?;)@kryger它满足了我的配额。
public ToDoItemDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
        insert = new SimpleJdbcInsert(dataSource).withTableName("toDoItem").usingGeneratedKeyColumns("id");
    }
<bean id="toDoItemDaoImpl" class="mypackage.ToDoItemDaoImpl">
    <constructor-arg ref="dataSource"/>
</bean>