【发布时间】: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