In my Spring 3 project I have the following bean definition
<bean name="account" class="sample.model.Account" scope="session">
<aop:scoped-proxy proxy-target-class="true" />
</bean>
CGLib 2.2 is on the class path, so according to the Spring documentation the account bean should be scoped to the http session of a client.
I populate the account bean when a user logs in, if no user is logged in the account bean is null. However, when using two browsers simultaneously to simulate two different http sessions and logging in on the one browser the other browser is also logged in. I interpret this behavior as the account bean not being scoped to the session
Any suggestions on this? Is there a way to check if a CGLib proxy has been created? When I debug the application and inspect the type of the injected account bean at runtime its sample.model.Account. I am not absolutely sure if this finally means that there was no CGLib proxying the cass.
Just set a breakpoint in the constructor, it should hit once per session
Related
We have an existing Spring MVC application (non Spring-boot application) with all (or most) of the beans configured in the XML. We wanted to use this as a Spring Cloud Config Client (we have a Spring Boot application acting as config server).
In this regard, what is the XML equivalent of configuring the beans in XML with refresh scope (same as #RefreshScope annotation). Tried configuring the RefreshScope as bean and using scope="refresh" but could see that the beans are not reflected with new values after peforming /refresh endpoint (from actuator)
Any help on this is highly appreciated
As pointed out in other answers 'refresh' scope is just another scope. However there's an issue where the bean properties are not updated with new values after /refresh call - if you define and inject properties in XML. More on the issue here. However the bean (i.e. actually the proxy) is instantiated after each /refresh call - but you need "aop:scoped-proxy" config since bean to which you inject the 'refresh' scoped bean, could be on a different scope. i.e.
<bean name="xmlValueBean" class="me.fahimfarook.xml.XMLValueBean" scope="refresh">
<aop:scoped-proxy proxy-target-class="true" />
</bean>
Well if you want to use #RefreshScope in core Spring(also Spring MVC) as people already pointed out, you have to implement the scope yourself also.
I also had the same dilemma and I did, I also wrote a blog about it, you can find there all the implementation details.
You can also use Spring Boot Configuration Server with your Spring MVC application, if you like to.
#RefreshScope for Spring MVC
#RefreshScope is just another scope. Look at how the RefreshScope class is implemented. It is creating a new scope named "refresh".
That means you should be able to use the new scope in your XML configuration, like this.
<bean id = "..." class = "..." scope = "refresh">
</bean>
consider a case when a prototype-scoped bean is injected into a singleton scoped bean,
when we try to access prototype-scoped bean using the singleton-scoped bean, we are returned with the same bean every time i.e. the bean injected at the time of singleton initialization.
if we want to get different instances everytime we use a scoped proxy.
I did not get the concept how this scoped proxy works behind the stage and how it magically gives us a new instance even if the bean is present inside a singleton.
From the Spring documentation:
3.4.4.5. Scoped beans as dependencies
Being able to define a bean scoped to a HTTP request or Session (or indeed a custom scope of your own devising) is all very well, but one of the main value-adds of the Spring IoC container is that it manages not only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If you want to inject a (for example) HTTP request scoped bean into another bean, you will need to 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 is smart enough to be able to retrieve the real, target object from the relevant scope (for example a HTTP request) and delegate method calls onto the real object.
…
To create such a proxy, you need only to insert a child element into a scoped bean definition (you may also need the CGLIB library on your classpath so that the container can effect class-based proxying; you will also need to be using Appendix A, XML Schema-based configuration). So, just why do you need this element in the definition of beans scoped at the request, session, globalSession and 'insert your custom scope here' level? The reason is best explained by picking apart the following bean definition (please note that the following 'userPreferences' bean definition as it stands is incomplete):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Are all controllers in Spring-MVC singletons and are shared among different sessions and requests?
If so, I assume that a class-variable like
public String name;
would be the same for all requests and sessions? So that if User X makes a request and name is being set to Paul, User Z also has Paul as attribute?
In my case I do NOT want that behaviour but wondered if there is a more easier, or more cleaner OOP-way to have session/request-variables then session.getAttribute()/request.getAttribute()
To answer your first question: yes, Spring MVC controllers are singletons by default. An object field will be shared and visible for all requests and all sessions forever.
However without any synchronization you might run into all sorts of concurrency issues (race conditions, visibility). Thus your field should have volatile (and private, by the way) modifier to avoid visibility issues.
Back to your main question: in Spring you can use request- (see 4.5.4.2 Request scope) and session-scoped (see: 4.5.4.3 Session scope) beans. You can inject them to controllers and any other beans (even singletons!), but Spring makes sure each request/session has an independent instance.
Only thing to remember when injecting request- and session-scoped beans into singletons is to wrap them in scoped proxy (example taken from 4.5.4.5 Scoped beans as dependencies):
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- instructs the container to proxy the surrounding bean -->
<aop:scoped-proxy/>
</bean>
Yes, controllers in Spring-MVC are singletons. Between multiple requests your class variable get shared and might result into ambiguity.
You can use #Scope("request") annotation above your controller to avoid such ambiguity.
I'm working on an application using Spring security.
The application is extensible and I would like to block extensions from programmatically changing the filters in the filter chain map of Spring's FilterChainProxy. What I intend to do is the following:
Implement a CustomFilterChainProxy implementing all of FilterChainProxy's implemented interfaces (Filter, InitializingBean, ApplicationContextAware). In it I will hold a private FilterChainProxy member and delegate all of the interface calls to it.
Use Spring's DelegatingFilterProxy by declaring in the web.xml file:
<filter>
<filter-name>customSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
In the Spring configuration files, instead of using Spring's FilterChainProxy directly I will have my bean have the CustomFilterChainProxy as its class, as follows:
<bean id="customSecurityFilterChain" class="....CustomFilterChainProxy">
<security:filter-chain-map ...>
<security:filter-chain pattern="..." filters="..." />
<security:filter-chain pattern="..." filters="..." />
...
</security:filter-chain-map>
</bean>
In order to be able to set the filter chain map during Spring bean loading I must supply a setter in my CustomFilterChainProxy class. That I will do. And in order to prevent setting the filter chain map after Spring bean loading I will make sure that after bean construction (in a #PostConstruct method) an exception will be thrown from that setter.
By having a CustomFilterChainProxy instead of a FilterChainProxy, am I causing any Spring process to malfunction?
I saw the only Spring class referencing the FilterChainProxy object itself is FilterChainProxyPostProcessor but couldn't find out if this should affect my implementation choice. Any input?
Thanks a lot.
This is unlikely to be sufficient to protect you from malicious extension code.
If the extension can access your bean, then it can also just access the original FilterChainProxy through the ApplicationContext. In fact, it can probably access any other bean in the same configuration, so it could potentially:
Load user account data, including passwords
Modify or read settings on other beans to break the system
Use reflection to read instance fields directly
Modify the current security context
Lots of other nasty things depending on what you are using
If you have untrusted code in your app then you would need to use a SecurityManager to prevent this kind of thing and you can then also prevent access to Spring Security classes. Configuring a SecurityManager can be a pain, but it's probably the only option if you have code you don't trust running in the same VM.
Update: If your only concern is preventing anyone from calling the setFilterChainMap method then overriding this method will obviously prevent anyone from accidentally calling this through a reference to your bean (this method is actually deprecated in 3.1 in favour of a constructor. However, it's not clear from your question why someone would obtain a reference to your instance rather than the original bean, or why this is your main concern. The FilterChainProxy is not normally accessed by user code in an application. To do so, you'd have to explicitly request it from the bean factory.
<bean id="userFacade" class="com.test.facade.UserFacadeImpl">
<property name="userDao" ref="userDao"/>
<property name="currentUser" ref="user"/>
</bean>
<bean id="user" class="com.test.beans.User" scope="session">
<aop:scoped-proxy/>
</bean>
UserDao and user are passed to it - user being a scope and facade a singleton. So any request to userfacade is going to return a same object but user will be different for each session - the concept session inside a singleton confuses me. Can someone explain?
The "scoped proxy" is a transparent wrapper around your User bean. When a method on that proxy is invoked, it will look up the current HttpSession using Spring's thread-local mechanism (called the RequestContextHolder), and then fetch the User object from inside the session's attributes. If none exists in that session, a new one is created and stored in the session. The "real" method on that User is then invoked.
The big caveat with scoped proxies is that the proxy's methods can only be invoked if the scope is "active", e.g. if the currently executing thread is a servlet request.
The instance of User injected into UserFacadeImpl is a proxy which delegates method calls to the actual session-scoped instances of User.
See also:
Proxy pattern