【问题标题】:@EnableTransactionManagement not working when in RootConfig@EnableTransactionManagement 在 RootConfig 中不起作用
【发布时间】:2017-09-28 20:54:31
【问题描述】:

我的 Spring (4.3.9-RELEASE) 配置有问题。

我正在运行一个 WebMVC 应用程序,并且在我当前的配置下一切正常。

由于复杂性的整体复杂性,我将省略很多我认为不重要的内容。如果您遗漏了重要内容,请告诉我。

@WebServlet 
@PropertySource("classpath:myAppConf.properties")
public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

        @Override
        protected Class<?>[] getRootConfigClasses() {
                return new Class[] {MainAppConfig.class } ;
        }

        @Override
        protected Class<?>[] getServletConfigClasses() {
                return new Class[] {WebAppConfig.class };
        }

        @Override
        protected String[] getServletMappings() {
                return new String[] { "/" };
        }

        @Override
        protected String getServletName() {
                return "myServletFooBar";
        }

}

MainAppConfig:

@Configuration
@Import({HibernateConfig.class})
@EnableGlobalMethodSecurity(prePostEnabled=true)
@ComponentScan(basePackages = { "my.app.security"})
public class MainAppConfig {
    ...
}

WebAppConfig:

@EnableWebMvc()
@Configuration()
@ComponentScan(basePackages = { "my.app.controller" })
@Import({ServiceConfig.class})
@EnableTransactionManagement
public class WebAppConfig extends WebMvcConfigurerAdapter{
    ...
}

我的WebAppConfiguration(带有@EnableTransactionManagement 注释)中有我所有的控制器和服务(带有@Transactional 注释)。我的 Hibernate 配置(事务管理器、数据源等)在我的 MainAppConfiguration 中。

事务在此配置下运行良好。

现在我需要在我的MainAppConfiguration-Context 中进行交易(用于定制的 Spring-Security AuthenticationProvider(从 DaoAuthenticationProvider 扩展)。

这不起作用,因为@EnableTransactionManagement 在我的WebAppConfig 上。当尝试从我的自定义身份验证提供程序运行事务时,我收到以下错误。

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

所以我尝试将我的所有服务移动到我的 MainAppConfig(也是 @EnableTransactionManagement 注释),但随后我在调用服务的 Controlloer 方法中收到相同的消息。

我还尝试将 @EnableGlobalMethodSecurity(prePostEnabled=true)@ComponentScan(basePackages = { "my.app.security"}) 注释从我的 MainAppConfig 移动到我的 WebAppConfig(我认为这更有意义)。但随后 Spring-Security 抱怨说,有No bean named 'springSecurityFilterChain' available

我的配置中的缺陷在哪里?

【问题讨论】:

  • 这个缺陷是你的配置是分散的,并且由于组件扫描而加载了两次。
  • 我看不到任何东西在这里加载了两次(你能指出我认为某些东西被加载了两次的地方吗?)我也不满意 RootConfig 和 WebAppConfig 的传播,但把所有东西都简单地放入 WebAppConfig不起作用(请参阅上面描述的我的SpringSecurityFilterChain 错误)。
  • 你是组件扫描的东西(不确定ServiceConfig 在哪个包中以及扫描的内容)......还有ServletInitializer 上的@webServlet@PropertySource 并不是真的有道理。
  • 我的my.app.security-package 上的组件扫描基本上加载了我的安全配置(用@EnableWebSecurity 注释)。在我的包中,我的所有类都用@Controller 注释所有我用@Transactional 注释的服务都在我的类WebAppConfig 中用@Bean 注释定义。所以我很确定,没有加载两次。该应用程序非常大,并且可以在生产中运行多年。我只是从未在我的 RootContext 中使用过事务。但现在我需要它......
  • 您的服务应该是事务边界,而不是控制器。所以基本上,如果你坚持这一点,你唯一需要做的就是将@Import@EnableTransactionManagement 移动到MainAppConfig。如果这不起作用,您的服务在被组件扫描错误的地方拾取(或者您正在以一种非常奇怪的方式做事)。

标签: spring spring-mvc spring-security spring-transactions


【解决方案1】:

感谢@M 的提示,我找到了一个适合我的解决方案。迪南:

我将所有服务移至 RootContext(在我的情况下为MainAppConfig.class)。但不是直接,我导入了另一个包含我所有服务豆的配置:

@Import(ServiceConfig.class)
public class MainAppConfig {
   ...
}

在我的ServiceConfig.class 中,我有我所有的服务-@Bean-定义。 重要的是,ServiceConfig 使用@EnableTransactionManagement 进行注释。如果你把它放在MainConfig-Class 事务上将不起作用。

@EnableTransactionManagement
public class ServiceConfig {
     @Bean(name="userService")
     UserService userService() {
         return new UserServiceImpl();      
     }
     ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    相关资源
    最近更新 更多