Có thể tạo nhà máy hoặc proxy có thể quyết định xem luồng có đang chạy trong (Web) Yêu cầu hoặc quá trình nền (tức là.) và sau đó tùy thuộc vào thông tin đó, nó tạo ra một bean phiên hoặc một bean nguyên mẫu?Mùa xuân: Tiêm đậu phụ thuộc vào ngữ cảnh (phiên/web hoặc quy trình địa lý/nền cục bộ)
Ví dụ (giả mùa xuân cấu hình :)
<bean id="userInfoSession" scope="session" />
<bean id="userInfoStatic" scope="prototype" />
<bean id="currentUserInfoFactory" />
<bean id="someService" class="...">
<property name="userInfo" ref="currentUserInfoFactory.getCurrentUserInfo()" />
</bean>
Tôi hy vọng điều này làm cho câu hỏi của tôi dễ dàng hơn để hiểu ...
Giải pháp của tôi
Đó là không bao giờ muộn để cập nhật câu hỏi của riêng mình;). Tôi đã giải quyết nó với hai phiên bản khác nhau của phiên ứng dụng khách, một phiên máy khách SessionScoped và một phiên SingletonScoped. Cả hai đều là đậu bình thường.
<bean id="sessionScopedClientSession" class="com.company.product.session.SessionScopedClientSession" scope="session">
<aop:scoped-proxy />
</bean>
<bean id="singletonScopedClientSession" class="com.company.product.session.SingletonScopedClientSession" />
<bean id="clientSession" class="com.company.product.session.ClientSession">
<property name="sessionScopedClientSessionBeanName" value="sessionScopedClientSession" />
<property name="singletonScopedClientSessionBeanName" value="singletonScopedClientSession" />
</bean>
Các ClientSession sau đó sẽ quyết định nếu singleton hoặc phiên phạm vi:
private IClientSession getSessionAwareClientData() {
String beanName = (isInSessionContext() ? sessionScopedClientSessionBeanName : singletonScopedClientSessionBeanName);
return (IClientSession) ApplicationContextProvider.getApplicationContext().getBean(beanName);
}
đâu loại phiên có thể được thu thập thông qua này:
private boolean isInSessionContext() {
return RequestContextHolder.getRequestAttributes() != null;
}
Tất cả các lớp học thực hiện một giao diện được gọi IClientSession. Cả hai hạt singletonScoped và sessionScoped mở rộng từ một BaseClientSession nơi thực hiện được tìm thấy.
Mỗi dịch vụ sau đó có thể sử dụng tức là phiên client:
@Resource
private ClientSession clientSession;
...
public void doSomething() {
Long orgId = clientSession.getSomethingFromSession();
}
Bây giờ nếu chúng ta đi thêm một bước nữa chúng ta có thể viết một cái gì đó giống như một Emulator cho phiên. Điều này có thể được thực hiện bằng cách khởi tạo clientSession (không có ngữ cảnh yêu cầu) phiên singleton. Bây giờ tất cả các dịch vụ có thể sử dụng clientSession cùng và chúng tôi vẫn có thể "bắt chước" một ví dụ sử dụng:
clientSessionEmulator.startEmulateUser(testUser);
try {
service.doSomething();
} finally {
clientSessionEmulator.stopEmulation();
}
hơn Một lời khuyên: chăm sóc về luồng trong SingletonScoped clientSession dụ! Wouw, tôi nghĩ rằng tôi có thể làm điều đó với ít dòng hơn;) Nếu bạn muốn biết thêm về cách tiếp cận này cảm thấy tự do để liên hệ với tôi.
Tôi sẽ thử. Đôi khi giải pháp đơn giản là tốt nhất và nếu nó hoạt động, tại sao nó không gọn gàng? Một số giải pháp khác? –
@Frank: Mã sử dụng 'RequestContextHolder' thường khó kiểm tra. Vì lý do đó, nó nên được nản lòng. – skaffman