At line 1 added 49 lines |
The RSACBridgeProxy is an absolutely invaluable architectural device for bridging between request scope and application scope. At an early stage during the invention of [RSAC], it became somewhat dismayingly apparent that the natural endpoint of a [request scope|RequestScopeBeans] design was to consist almost ''entirely'' of request-scope beans - since it is seemingly impossible to make a bean with a dependency which has a shorter scope than oneself. Much like "const"-ness in C++, "request-scopeness" would ripple outwards through a design, infecting probably the majority of a webapp's logic by placing it into the request scope. |
|
In an "ideal" world this wouldn't be too much of a problem - unfortunately while [RSAC] is fast, it is not ''that'' fast - with a ThreadLocal get running at 60ns, while an RSAC bean construction at perhaps 20x that, the request-time cost mounts up quite quickly. While having ''some'' RSACed beans becomes indispensable in terms of the design benefits they bring, being forced to have the ''majority'' of request-scope logic defined in them would be a real liability. |
|
AOP to the rescue. Spring since its very earliest days has defined a very generalised framework, under the banner [AOPAlliance|http://aopalliance.sourceforge.net/] for bytecode manipulation, proxying, and "Aspect-Oriented Programming" of various kinds. While I'm still very much at odds with Aspects as a design principle, when used for proxying and stubbing of these kinds of AOP can be absolutely invaluable as an ''optimisation''. RSF will also upgrade itself to use a similar scheme, [FastClass] for its internal reflection shortly. |
|
The basic idea of RSACBridgeProxy is quite simple - it is an application-scope bean that "masquerades as" (i.e. is a proxy for) different request-scope beans when accessed from different requests. By provided RSAC architecture (and I think any feasible one) a request is bound to a particular ''thread'', which guides the [RSACBeanLocator] to find the relevant container of request-scope beans. |
|
RSF provides a useful parent bean definition, also called {{RSACBridgeProxy}} that makes defining a bridge proxy bean as simple as possible - all you do is provide the name of the target request-scope bean as a property as follows: |
|
{{{ |
<bean id="RSACSafeBeanLocatorProxy" parent="RSACBridgeProxy"> |
<property name="targetBeanName" value="RSACSafeBeanLocator" /> |
</bean> |
}}} |
|
Some caveats with bridged beans: |
|
* Naturally you must be careful only to access methods of bridged beans while actually executing in a proper request scope - otherwise you will simply trigger a creation exception. |
* The cost of ''each access'' (i.e. method call) to a bridged bean is magnified by a ThreadLocal get and several other method calls incurred inside the proxy. Be aware of this when costing up your architecture. |
* You may not proxy [Peas] in this way - be aware that you will simply find default values when looking at the fields of any proxied bean, either in code or in the debugger! This is precisely the defined behavior - the proxy is a CGLib-synthesised class ''derived'' from the expected class or interface which has been default-constructed, holding a reference to the context whereby the real bean may be located dynamically via Spring's TargetSource's {{getTarget}} method. |
* However, you may proxy peas using a special mode of the RSACBridgeProxy - this is explained on its own page on [PeaProxies|PeaProxy]. |
|
But the uses of this technique are quite fruity - for example, another RSF definition is as follows: |
|
{{{ |
[ at request scope] |
<bean id="httpSession" factory-bean="httpServletRequest" factory-method="getSession"/> |
[ at application scope] |
<bean id="httpSessionProxy" parent="RSACBridgeProxy"> |
<property name="targetBeanName" value="httpSession"> |
</property> |
</bean> |
[ in code ] |
public class InSessionTSH implements TokenStateHolder { |
private HttpSession session; |
|
public void setSession(HttpSession session) { |
this.session = session; |
} |
}}} |
|
Yes, a properly IoC-delivered proxy for the HttpSession, delivered over massive code distances into a bean which isn't even request-scope! Use this ability sparingly since it can cause considerable confusion - but in general is an elegant and clean solution to a quite knotty problem. |
|
|
---- |
%%(color: #666666; font-family: sans-serif; font-size:80%)You can post comments and questions on this page using the following blog. Please set your name using [UserPreferences] before posting.%% |
[{INSERT WeblogPlugin}] |
[{INSERT WeblogEntryPlugin}] |