2012-05-10 26 views
9

Tôi đang sử dụng Spring 3 AOP và tôi có một khía cạnh yêu cầu quyền truy cập vào HttpServletRequest. Nó trông giống như sau:Spring AOP và an toàn chủ đề khía cạnh cho một bean HTTPServletRequest tự động

@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... 
    } 
} 

Và được cấu hình như thế này:

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

Là phương pháp init chỉ gọi một lần mỗi IoC container, mặc dù đây là một khía cạnh, và là chủ đề an toàn HttpServletRequest ? Nếu nó không phải là, cách tốt nhất để có được nó trong quá trình thực hiện các lời khuyên và có nó được thread an toàn? Nếu có thể tôi không muốn sử dụng một chủ đề địa phương.

Trả lời

16

Là phương pháp init chỉ gọi một lần mỗi IoC container

Nó được gọi là một lần mỗi mỗi trường hợp đậu. Nếu đậu có một phạm vi singleton (đó là trường hợp mặc định cho các khía cạnh là tốt), nó sẽ chỉ được gọi một lần. Tuy nhiên, bạn sẽ không có quyền truy cập vào phương thức httpServletRequest bên trong init() - chưa có yêu cầu nào!

là an toàn

chủ đề HttpServletRequest Nó không phải là nhưng đừng lo lắng. Điều này thực sự phức tạp hơn rất nhiều. Bạn đang tiêm yêu cầu HTTP servlet (và rõ ràng là có thể có một số yêu cầu có sẵn cùng một lúc) vào một đối tượng đơn lẻ. Cái nào được tiêm? Không ai (tất cả?) Của họ! Mùa xuân tạo ra một số proxy phức tạp (được gọi là proxy phạm vi) và mỗi khi bạn truy cập các phương pháp được tiêm httpServletRequest, nó ủy quyền cho yêu cầu hiện tại (tới chuỗi). Bằng cách này, bạn có thể chạy các khía cạnh của mình một cách an toàn trong một số luồng - mỗi luồng sẽ hoạt động theo một yêu cầu vật lý khác nhau.

hành vi toàn này được mô tả chi tiết tuyệt vời trong 4.5.4.5 Scoped beans as dependencies:

[...] Nếu bạn muốn bơm (ví dụ) một yêu cầu HTTP scoped đậu vào một đậu, bạn phải tiêm một Proxy AOP thay cho bean có phạm vi. Tức là, bạn cần tiêm một đối tượng proxy để lộ giao diện công cộng giống như đối tượng phạm vi nhưng cũng có thể truy lục đối tượng đích thực từ phạm vi có liên quan (ví dụ, yêu cầu HTTP) và gọi phương thức ủy nhiệm vào đối tượng thực .

Về ThreadLocal:

Tôi không muốn sử dụng một thread địa phương.

May mắn thay - Mùa xuân đang sử dụng một cho bạn. Nếu bạn hiểu cách hoạt động của ThreadLocal - Spring sẽ đặt yêu cầu hiện tại vào một chuỗi địa phương và ủy quyền cho cá thể cục bộ khi bạn truy cập httpServletRequest proxy.

+0

Tom, đây là một câu trả lời tuyệt vời. Liệu Spring có thể có tài liệu này ở đâu đó mà tôi có thể đọc được không? Rất khó để tìm thấy bất cứ điều gì liên quan đến cách proxy thực sự hoạt động.Oh, và tôi không cần truy cập vào yêu cầu từ bên trong init() - đó là tôi gian lận và ép hai câu hỏi thành một :) –

+0

@BrianReindel: Tôi bao gồm tham chiếu đến tài liệu Spring trong câu trả lời của tôi. –

+0

Hi Thomasz, mã sẽ hoạt động trong câu trả lời? Bạn cũng có thể đưa ra ý kiến ​​của mình về "http://stackoverflow.com/questions/22923813/set-systems-property-in-controller-and-access-that-in-an-aspect" – riship89

Các vấn đề liên quan