Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ways to autowire request scoped bean

I just wonder if there is any other way to autowire a request scoped bean. So for now I created a bean in configuration file:

@Bean
@Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.DEFAULT)
public List<String> stringBean(){
    return new ArrayList<String>();
}

So normally I would autowire the applicationContext to use the bean:

@Autowired
private ApplicationContext context; 

@Override
public void anyName() {
    List<String> list = (List<String>) getContext().getBean("stringBean");
}

This works totally fine. But I dont like to autowire the context and the need of a cast. So I tried to autowire the bean directly:

@Autowired
private List<String> stringBean;

I got an exception by startup of the application what is also clear because the bean is not created before a request is started.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stringBean': 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 receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

Are there other ways to autowire a request scoped bean?

like image 903
Patrick Avatar asked Dec 14 '22 22:12

Patrick


1 Answers

ScopedProxyMode.DEFAULT, if you have not configured any, means NO (a proxy is not created). Try using ScopedProxyMode.TARGET_CLASS in order to use a CGLIB proxy

As you already know, singleton beans are only created once and their dependency injections are made at initialisation time. As you said in your question, for request scoped beans that beans do not exist at that point and you get the exception.

To avoid that, you need to let Spring know you want to use a proxy bean. A proxy bean is just a bean created dynamically by Spring and exposing the same public interface that the one you are targeting. This proxy bean is the one Spring is going to inject in your beans and when calling its methods is going to delegate the call to the real one created for that request.

There are two proxying mechanisms: JDK dynamic proxies, when using interfaces (ScopedProxyMode.INTERFACES) or CGLIB (ScopedProxyMode.TARGET_CLASS).

I hope you get the idea.

Have a look to some useful documentation:

Scoped beans as dependencies

Choosing the type of proxy to create

Proxying mechanisms

Aspect Oriented Programming with Spring

like image 120
alfcope Avatar answered Jan 12 '23 06:01

alfcope