3

我有一个带有注释驱动配置的 spring webapp。

所有控制器、存储库都是自动装配的。

在集成 Spring Security 时,我定义了一个单独的 security-app.xml。我创建了一个名为 LoginUserService 的服务,它实现了 UserDetailsS​​ervice。现在调用这个类的 loadUserByUsername() 方法进行身份验证。

此类具有对 UserRepository 的自动装配依赖项。现在这个自动装配的依赖项变成了空值。为了解决这个问题,我启用注释驱动配置并在组件扫描配置中添加存储库类的包名称。

此处还讨论了此解决方案 spring security with custom user details

但现在的问题是 UserRepository 有一个带有 @PersistenceContext 注释的 EntityManager 字段。对于 spring 安全配置,它能够定位 UserRepository 但无法定位实体管理器。我应该在这里创建一个新的 EntityManagerFactory 吗?我猜这会在我的应用程序中创建两个持久性单元?

如何将自动装配的依赖项注入使用原始 servlet xml 创建的 UserRepository?

更新

这在这里简要讨论: https ://stackoverflow.com/a/7078395/161628

但我想一个规范的详细答案对我来说会更有用。

更新

在运行时使用 ApplicationContext 获取 UserRepository 怎么样?

if (userRepository == null) {
    userRepository = ApplicationContextProvider.getApplicatonContext().getBean(UserRepository.class);
}

为什么 Spring 的 ApplicationContext.getBean 被认为不好?

4

1 回答 1

1

编辑:您在 DispatcherServlet 的配置中声明的 Bean 将不可用于您在 contextConfigLocation 配置文件中声明或组件扫描的任何 bean。因此,在这种情况下,如果您在为 DispatcherServlet 加载的配置文件中设置 JPA 配置,则无法将其连接到您在安全配置中声明的 bean。您需要将任何类似的“核心”bean 配置(数据源配置、数据库连接池配置、JPA/Hibernate 配置、存储库/服务组件扫描等)移动到您通过 contextConfigLocation 加载的配置文件中。然后,您的安全 bean 和 MVC bean 都可以使用这些东西。我认为通常的想法是只在 DispatcherServlet 配置中加载 MVC 特定的 bean(例如控制器、视图、请求处理程序、请求范围内的 bean 等)。这样你就可以确保你在 MVC 代码和非 MVC 代码之间有一个清晰的分离,只有从 MVC 代码到“核心”代码的单向依赖,并且在你的“核心”代码中没有对 MVC 代码的依赖。这有助于使您的代码更加模块化,并更容易以其他方式重用您的“核心”代码,特别是在单元测试中。

(原始评论文本询问如何加载安全配置,如果它在 contextConfigLocation 或其他地方。)

于 2013-05-09T06:03:58.027 回答