自动连接的HTTPServletRequest bean的Spring AOP和方面线程安全性 [英] Spring AOP and aspect thread safety for an autowired HTTPServletRequest bean

查看:319
本文介绍了自动连接的HTTPServletRequest bean的Spring AOP和方面线程安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring 3 AOP,并且我有一个方面需要访问HttpServletRequest.看起来像这样:

I am using Spring 3 AOP, and I have an aspect that requires access to the HttpServletRequest. It looks something like this:

@Aspect
public class MyAspect {

    @Autowired
    private HttpServletRequest httpServletRequest;

    public void init() {
        // Do something once...
    }

    @Before("my pointcut here...")
    private void myMethod() {
        // I need the httpServletRequest...
    }

    @After("my pointcut here...")
    private void myOtherMethod() {
        // I need the httpServletRequest...
    }
}

并且配置如下:

<bean id="myAspect" class="com.some.package.MyAspect" init-method="init" />

即使这是一个方面,init方法在每个IoC容器中仅被调用一次,并且httpServletRequest线程安全吗?如果不是,那么在执行建议期间获取建议并使其具有线程安全性的最佳方法是什么?如果可能的话,我宁愿不要使用本地线程.

Is the init method only called once per IoC container, even though this is an aspect, and is the httpServletRequest thread safe? If it is not, what is the best way to get at it during execution of the advice and have it be thread safe? If at all possible I prefer not to use a thread local.

推荐答案

每个IoC容器仅调用一次init方法

Is the init method only called once per IoC container

每个实例调用一次.如果bean具有单例作用域(这也是方面的默认情况),它将仅被调用一次.但是,您将无法访问init()方法中的httpServletRequest-尚无请求!

It is called once per every bean instance. If bean has a singleton scope (which is the default case for aspects as well), it will only be called once. However you won't have access to the httpServletRequest inside init() method - there is no request yet!

httpServletRequest线程是否安全

is the httpServletRequest thread safe

不是,但是不用担心.这实际上比看起来要复杂得多.您正在将HTTP servlet请求(显然可以同时有多个请求)注入到一个singleton对象中.注入哪一个?没有一个(全部?)! Spring创建了一些复杂的代理(称为 scoped代理),每次您访问注入的httpServletRequest方法时,它将它们委托给 current (线程)请求.这样,您可以在多个线程中安全地运行方面-每个方面都将在不同的物理请求上运行.

It is not but don't worry. This is actually much more complex than it looks like. You are injecting HTTP servlet request (and obviously there can be several requests available at the same time) into a singleton object. Which one is injected? None (all?) of them! Spring creates some sophisticated proxy (called scoped proxy) and every time you access methods of injected httpServletRequest it delegates them to current (to thread) request. This way you can safely run your aspects in several threads - each will operate on a different physical request.

[...]如果要例如将HTTP请求范围的bean注入另一个bean ,则必须注入AOP代理来代替范围的bean.也就是说,您需要注入一个代理对象,该代理对象公开与范围对象相同的公共接口,但还可以从相关范围(例如,HTTP请求)中检索实际的目标对象,并将委托方法调用到实际对象上

[...] If you want to inject (for example) an HTTP request scoped bean into another bean, you must inject an AOP proxy in place of the scoped bean. That is, you need to inject a proxy object that exposes the same public interface as the scoped object but that can also retrieve the real, target object from the relevant scope (for example, an HTTP request) and delegate method calls onto the real object.

关于ThreadLocal:

我不想使用本地线程.

I prefer not to use a thread local.

幸运的是-Spring正在为您使用一个.如果您了解ThreadLocal的工作原理-当您访问httpServletRequest代理时,Spring会将当前请求放入本地线程,并委托给本地线程实例.

Fortunately - Spring is using one for you. If you understand how ThreadLocal works - Spring puts current request into a thread local and delegates to thread-local instance when you access httpServletRequest proxy.

这篇关于自动连接的HTTPServletRequest bean的Spring AOP和方面线程安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆