相关疑难解决方法(0)

ContextLoaderListener与否?

标准的Spring Web应用程序(由Roo或"Spring MVC Project"模板创建)使用ContextLoaderListener和创建一个web.xml DispatcherServlet.为什么他们不仅使用DispatcherServlet并使其加载完整的配置?

我知道ContextLoaderListener应该用于加载非Web相关的东西,而DispatcherServlet用于加载与Web相关的东西(Controllers,...).这导致两个上下文:父上下文.

背景:

几年来我一直以这种标准方式做这件事.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Handles Spring requests -->
<servlet>
    <servlet-name>roo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
Run Code Online (Sandbox Code Playgroud)

这通常会导致两个上下文及其之间的依赖关系出现问题.在过去,我始终能够找到解决方案,我强烈认为这使得软件结构/架构总是更好.但现在我面临着两种情境事件的问题.

- 然而这让我重新思考这两个上下文模式,我问自己:为什么我要把自己带入这个麻烦,为什么不用一个加载所有弹簧配置文件DispatcherServletContextLoaderListener完全删除.(我仍然会有不同的配置文件,但只有一个上下文.)

有没有理由不删除ContextLoaderListener

java spring servlets dependency-injection

122
推荐指数
3
解决办法
5万
查看次数

在实际Web请求之外使用请求范围的bean

我有一个Web应用程序,它在一个独立的线程中运行Spring Integration逻辑.问题是,在某些时候,我的Spring Integration逻辑尝试使用请求范围的bean,然后我得到以下错误:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.tenantContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still …
Run Code Online (Sandbox Code Playgroud)

spring spring-integration spring-aop

23
推荐指数
4
解决办法
5万
查看次数

在多线程Web应用程序中访问请求范围的bean

场景:我们有一个在Websphere中运行的Spring托管Web应用程序.(Spring 3.0.x,WAS 7)webapp通过Spring WorkManagerTaskExecutor(配置线程池大小为10)利用Websphere的工作管理器来执行计算密集型数据库读取操作.所以基本上,一个请求来生成,比方说,生成10个不同的文档.要生成文档,只需要db读取来收集/处理数据.因此,我们基本上产生10个线程来处理10个文档,最后收集10个工作者返回的10个文档并合并它们并向客户端写回一个大响应.我们确定的是,当10个线程正在收集/处理数据时,会产生大量类似的数据库调用.所以我们想出的是围绕最常执行的db方法创建一个Aspect来缓存响应.方面配置为单例,方面使用的缓存自动连接到方面,并将范围设置为请求范围,以便每个请求都有自己的缓存.

问题:现在这个方法的问题是,当线程正在进行数据库调用而Aspect是interjects时,我们会遇到java.lang.IllegalStateException: No thread-bound request found异常.我理解的是完全有效的,因为线程正在请求上下文之外执行.

有没有办法绕过这个问题?是否可以将带有请求范围缓存的方面应用于这些线程调用的方法?

java spring multithreading

8
推荐指数
1
解决办法
1万
查看次数

如何使用no-xml配置添加RequestContextListener?

我需要在我的Spring Boot应用程序中添加一个监听器,在web.xml中看起来像

<listener>
 <listener-class>
    org.springframework.web.context.request.RequestContextListener
 </listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)

我使用no-web.xml配置,所以我有一个类似的

public class AppFilterConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Filter[] getServletFilters() {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF8");
    filter.setForceEncoding(true);
    Filter[] filters = new Filter[1];
    filters[0] = filter;
    return filters;
}

private int maxUploadSizeInMb = 5 * 1024 * 1024; // 5 MB

@Override
protected Class<?>[] getRootConfigClasses() {
    return null;
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return null;
}

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

@Override
protected void registerDispatcherServlet(ServletContext servletContext) { …
Run Code Online (Sandbox Code Playgroud)

java spring spring-boot oauth2

8
推荐指数
1
解决办法
9982
查看次数

Java/Spring MVC:为子线程提供请求上下文

我有问题,我想将我的Spring WebMVC应用程序的一些进程外包到单独的Threads中.这很容易并且有效,直到我想使用一个使用全局请求的类userRightService.这在线程中不可用,我们遇到了一个问题,这几乎是可以理解的.

这是我的错误:

java.lang.RuntimeException:
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'scopedTarget.userRightsService': Scope 'request' is not active
for the current thread; consider defining a scoped proxy for this bean if
you intend to refer to it from a singleton; nested exception is 
java.lang.IllegalStateException: Cannot ask for request attribute - 
request is not active anymore!
Run Code Online (Sandbox Code Playgroud)

好的,够清楚了.我试图通过实现此解决方案来保持请求上下文:

如何在异步任务执行程序中启用请求范围

这是我的runnable类:

@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class myThread implements Runnable {

  private RequestAttributes context;

  public DataExportThread(RequestAttributes context) {
    this.context = context;
  }

  public …
Run Code Online (Sandbox Code Playgroud)

java spring multithreading spring-mvc

8
推荐指数
1
解决办法
3040
查看次数

在 Spring Boot 中,继承的 ServletRquestAttributes 在子线程完成之前被标记为完成

我正在使用 SpringBoot 1.5.2 版本。我有一个异步 REST 调用,它会生成单独的 java 线程来完成长时间运行的作业。长时间运行的作业需要更新数据库表,我在其中配置了 Spring 审核 bean 以使用当前登录用户名更新表。我遇到的问题是:通过调用 setThreadContextInheritable(true) 启用可继承标志后,传递给执行长时间运行的数据库更新的子线程的 ServletRequestAttributes 对象在子线程完成其工作之前被标记为“非活动”,最终导致当审核 bean 尝试从 RequestContextHolder 中缓存的 ServletRequestAttributes 访问用户名时出错。

要打开可继承标志,请参阅Scope 'session' is not active for the current thread; IllegalStateException:未找到线程绑定请求

这是获取我到目前为止所拥有的内容的主要代码:

  1. 应用程序.java中
@Override
public Executor getAsyncExecutor() {
    SimpleAsyncTaskExecutor executor = new
        SimpleAsyncTaskExecutor(appProperties.threadNamePrefix);
    return executor;
}
@Bean
public ServletRegistrationBean registerAirportDispatchServlet() {
    DispatcherServlet dispatcherServlet = new DispatcherServlet();
    AnnotationConfigWebApplicationContext applicationContext =
        new AnnotationConfigWebApplicationContext();
    dispatcherServlet.setApplicationContext(applicationContext);
    dispatcherServlet.setThreadContextInheritable(true);
    ServletRegistrationBean servletRegistrationBean =
        new ServletRegistrationBean(dispatcherServlet, "/*");
    servletRegistrationBean.setName("AirportSCSDispacherServlet");
    return servletRegistrationBean;
}
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, …
Run Code Online (Sandbox Code Playgroud)

java spring-mvc spring-boot

5
推荐指数
1
解决办法
2373
查看次数

尽管定义了RequestContextListener,但在创建名为'scopedTarget.oauth2ClientContext'的bean时出错

我的应用程序有多个弹簧安全配置,其中一个恰好是Oauth2(使用 eaxmple).

一般来说Spring安全性通过以下方式插入:

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);             
context.addFilter(GzipFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
context.addFilter(new FilterHolder( new DelegatingFilterProxy( DEFAULT_FILTER_NAME ) ), "/*",EnumSet.allOf( DispatcherType.class ));
AnnotationConfigWebApplicationContext securityContext = new AnnotationConfigWebApplicationContext();
securityContext.setConfigLocation("com.test.auth");
DispatcherServlet dispatcherServlet = new DispatcherServlet(securityContext);
context.addServlet(new ServletHolder(dispatcherServlet), "/");
context.addServlet(new ServletHolder(new ServletContainer(createResourceConfig(AuthController.class))), "/auth/*");
Run Code Online (Sandbox Code Playgroud)

Oauth2看起来像这样:

@Order(4)
@EnableOAuth2Client
@EnableWebSecurity
@Configuration  
public class Oauth2Config extends WebSecurityConfigurerAdapter {    
        @Bean
        @Order(0)
        public RequestContextListener requestContextListener() {
            return new RequestContextListener();
        }

        @Autowired
        private OAuth2ClientContext oauth2ClientContext;

        @Autowired
        private OAuth2ClientContextFilter oauth2ClientContextFilter;

        @Autowired
        private AuthConfig authConfig;

        private OAuth2ProtectedResourceDetails authorizationCodeResource() {
            AuthorizationCodeResourceDetails …
Run Code Online (Sandbox Code Playgroud)

java spring spring-security spring-security-oauth2

3
推荐指数
1
解决办法
9190
查看次数