我使用Spring并尝试将DAO自动装配(使用注释)到服务中,然后将其连接到控制器。
@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();
}
这段代码在我的Service类中。是否有更优雅的方法来确保我的DAO正确初始化,而不是将该方法的前4行复制并粘贴到每个Service方法中?
[edit]包含上面代码的类是一个名为MovieServiceImpl的类,它实际上对应于this page中描述的体系结构中的DataServicesImpl类。 (我将添加该架构的摘要/描述以及我即将尝试做的事情)。这是代码:http://pastebin.com/EiTC3bkj
答案 0 :(得分:1)
我认为主要问题是您希望直接实例化您的服务(使用new
)而不是Spring:
MovieService movieService = new MovieServiceImpl();
执行此操作时,您的MovieServiceImpl
实例已构建但未初始化(字段@Autowired MovieDao
为null
)。
如果要使用字段注入正确实例化对象,则需要使用Spring。如documentation或this example中所述,您可以自动检测所有带注释的bean,并使用组件扫描在您的上下文中对其进行初始化。
在您的情况下,在(@Component
,@Service
等)和 (@Autowired
,{{中使用注释 1}}等你的bean,你的项目看起来像这样:
@Inject
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
事实上,当您使用Spring时,了解如何初始化上下文非常重要。在上面的例子中,它可以总结为:
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);
}
}
已被调用。App#main
由app-context.xml
加载。ClassPathXmlApplicationContext
扫描包com.se325.a01
。所有带注释的bean(<context:component-scan base-package="com.se325.a01" />
,@Component
等)都已构建但尚未初始化。@Service
,还会发现标记依赖关系的@Autowired
注释。所有这些答案都解释了如何使用组件扫描和注释在<context:component-scan ... \>
入口点中使用Spring。但是,如果您正在开发服务器应用程序,则入口点为main
。
正如@chrylis所说,现场注入容易出错。 首选使用基于构造函数的注入。