How to instantiate Spring bean with custom scope and @Autowired dependencies?

情到浓时终转凉″ 提交于 2019-12-05 07:16:48

问题


In our project, we use Spring request scoped beans. Now we've a requirement to support async requests and request scoped beans don't work for child threads. I'm aware of RequestContextFilter and it's "support" for async but it appears that RequestContextFilter expects the main thread to wait for the child threads to finish, which isn't the case for us. Our main thread immediately returns after spawning new threads using @Async annotation and DispatcherServlet clears out the RequestContextHolder. Thus when the child threads get to the point where they need a request scoped bean, @Autowired fails.

I'm also aware of SimpleThreadScope but it doesn't clean up thread-local attributes and in a thread-pooling situation, is not only dangerous to use but downright useless.

What I need is a custom scope. So far, I've found 3 useful examples but all of them fall short in that the beans they instantiate as part of the custom scope are plain POJOs without any dependencies. Needless to say that's non-existent in a real life application. Can anyone suggest a way to instantiate custom scoped beans that have @Autowired dependencies on beans from other scopes?

What I found so far:

https://github.com/spring-by-example/spring-by-example/tree/master/modules/sbe-thread-scope/src/main/java/org/springbyexample/bean/scope/thread

https://github.com/billkoch/spring-async-mdc

Spring Bean Custom Scope JMS


回答1:


Continuing the discussion from the other question's answer here...

See the Spring Documentation about scoped beans as dependencies.

.

I'm referring to the <aop:scoped-proxy/> which is what the link points to. Each time the autowired field is referenced, your custom scope's get() method is called to lookup the instance based on some criteria.

.

I understand I can look up the dependencies (though unsure how, a scope isn't a bean, perhaps I need to pass application context during instantiation?). What I don't understand is how to inject those dependencies into my bean if those're marked @Autowired? Or are you saying the custom scoped bean shouldn't have @Autowired dependencies?

It works automatically; Spring injects a proxy for the bean and the scope.get() is invoked on every method call on that bean, returning the specific instance you want in the context of the current invocation.

Take a look at the AbstractRequestAttributesScope to see how it works (in that case, gets the instance from the HTTP Request and, if it doesn't exist, creates it).

So, your code calls foo() on the proxy; the framework calls the scope to get the desired instance and then calls foo() on that instance.

The exposed methods you wish to call must either be on an interface or not declared final.



来源:https://stackoverflow.com/questions/30842242/how-to-instantiate-spring-bean-with-custom-scope-and-autowired-dependencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!