我正在使用 Spring 并尝试将 DAO Autowiring (使用注释)到服务中,然后将其连接到 Controller 中。拥有
@Autowired
Movie movieDao;
本身不起作用,因为我认为调用了 new
方法,因此 DAO 不由 Spring 管理。以下确实有效,但如果我必须将该上下文配置复制并粘贴到每个方法中,它看起来会很乱
@Autowired
MovieDao movieDao;
@Override
public List<Movie> findAll() {
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.load("classpath:app-context.xml");
context.refresh();
MovieDao movieDao = (MovieDao) context.getBean("movieDao", MovieDao.class);
return movieDao.findAll();
}
此代码在我的服务类中的位置。有没有更优雅的方法来确保正确初始化我的 DAO,而不是将该方法的前 4 行复制并粘贴到每个服务方法中?
[edit] 包含上述代码的类是一个名为 MovieServiceImpl 的类,它本质上对应于 this page 中描述的体系结构中的 DataServicesImpl 类。 . (我将添加该架构的摘要/描述以及我即将尝试做的事情)。这是代码:http://pastebin.com/EiTC3bkj
最佳答案
我认为主要问题是您想直接实例化您的服务(使用 new
)而不是使用 Spring:
MovieService movieService = new MovieServiceImpl();
当你这样做时,你的 MovieServiceImpl
实例已构造但未初始化(字段 @Autowired MovieDao
是 null
)。
如果你想通过字段注入(inject)正确地实例化你的对象,你需要使用 Spring。如 documentation 中所述或在 this example ,您可以自动检测所有带注释的 bean 并使用组件扫描在您的上下文中初始化它们。
例子
在你的例子中,使用注释on(@Component
,@Service
,等等)和in(@Autowired
,@Inject
,等等)你的bean ,您的项目可能如下所示:
Spring 配置app-context.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Use component scanning to auto-discover your beans (by annotation) and initialize them -->
<context:component-scan base-package="com.se325.a01" />
<!-- No need to declare manually your beans, because beans are auto-discovered thanks to <context:component-scan/> -->
</beans>
您的应用程序的入口点 App.java
package com.se325.a01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.se325.a01.model.Movie;
import com.se325.a01.service.MovieService;
public class App {
public static void main(String[] args) {
// Let's create the Spring context based on your app-context.xml
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"app-context.xml"});
// Now your context is ready. All beans are initialised.
// You can retrieve and use your MovieService
MovieService movieService = context.getBean("movieService");
Movie matrixMovie = new Movie("Matrix");
movieService.create(matrixMovie);
}
}
其实,当你在使用Spring的时候,理解上下文是如何初始化的真的很重要。在上面的例子中,可以总结为:
- 您的入口点
App#main
被称为。 - 配置
app-context.xml
由ClassPathXmlApplicationContext
加载. - 包裹
com.se325.a01
由于行<context:component-scan base-package="com.se325.a01" />
被扫描.所有带注释的 bean(@Component
、@Service
等)都已构建但尚未初始化。 - 当所有 bean 都构建完成后,Spring 通过注入(inject)依赖项来初始化它们。在示例中,
@Autowired
由于<context:component-scan ... \>
行,还发现了标记依赖关系的注释. - 上下文已准备好所有 bean :)
注意事项
所有这些答案都解释了如何使用组件扫描和注释在 main
中使用 Spring入口点。但是,如果您正在开发服务器应用程序,则入口点是 WEB-INF/web.xml
.
正如@chrylis 所说,字段注入(inject)很容易出错。 更喜欢使用基于构造函数的注入(inject)。
关于java - 将 DAO Autowiring 到服务中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25839186/