I use spring 5.2.10 for dependecies injection with spring mvc. In the first call from client no beans persist in session. Each time i get a bean from the context during the first call from client, Spring creates it again. It seams that Spring doesn't update the beans repository after create one of them.
It´s more, if i try to retrive a bean just after setting it the result is null.
Why did the bean disapear after having set it?
Thanks
Related
Using Spring Boot 1.5.12, we create scoped proxies for #ConfigurationProperties beans. We do this so that we can effectively have property values that are scoped to the user/session/etc. We use a BeanFactoryPostProcessor to register a scoped proxy created by ScopedProxyUtils.createScopedProxy and change the scope of the target bean definition to our custom scope.
This worked great in Spring Boot 1.5.12. However, in Spring Boot 2, the introduction of the Binder API has made this stop working. This is because when Spring Boot binds #ConfigurationProperties in its ConfigurationPropertiesBindingPostProcessor, it uses Bindable.of(type).withExistingValue(bean) passing in a type (e.g. org.example.Foo) and the bean which is an instance of ScopedProxyFactoryBean. Bindable checks that bean is an instance of type which it's not and things blow up.
Does anyone know of a general way to accomplish this? Specifically, to replace the #ConfigurationProperties bean definition with a proxy while still allowing the properties to bind to the instance? I've considered delaying the creation of the proxy until after the target has already been bound by ConfigurationPropertiesBindingPostProcessor (i.e. in my own BeanPostProcessor). However, at this point the bean is instantiated and my proxy can only replace the bean. It can't really leave the original bean in the context as a target. So I'm struggling with how to do this using a BeanPostProcessor.
EDIT: I've created a simple example project that demonstrates the issue (with the ability to check out code that works on Spring Boot 1 and fails on Spring Boot 2).
I'm building an online chat application in spring just like the one on Facebook. I want to create a bean with a property[Array] called active-users. Then performs the following:
Whenever a user logs in, I'll add his/her userId into the array.
When an other user logs in, I'll display the users that are
currently online.
How do I create a bean which is available at all times?
For Ex : In servlets, this can be achieved by using the Servlet context :
ServletContext context = request.getServletContext();
context.setAttribute("userId", "123");
All beans in Spring are singletons by default, they will be alive during the whole application's lifecycle unless you'll do something with the spring context.
So just create a spring bean and declare a global list in it. You can access it anywhere where the spring bean will be injected from the current context.
It's simpler with Spring than in a pure servlet application, because all beans declared in root application context reside in fact automatically in the ServletContext and as such are unique in the application. And Spring can natively inject them in any controller or service bean to allow you to use them at will.
The only limit, is that they are unique per instance, so it won't be enough it you had a farm of servers for your application.
Is there a way to update a Spring bean dynamically if the spring beans configuration changes?
E.g. assume that I have a spring bean with boolean property x and the spring beans has the value true when the application starts.
So spring creates the bean with the property x set to true.
Is there a way so that if I changes the property to x (while the application is running) that the property will be updated e.g. to false?
Calling the setter for x setX() method will do that.
But it should not be a prototype bean.
it is possible with the jrebel-spring integration. it monitors your configuration and TRIES to re-wire your beans at runtime.
Though i would not use it in production...only for playing around, testing etc
Spring reads configuration files at startup. If you really need to update configs while application running, you should manually implement all the chain: detecting config changes, validating config, detecting changed beans, updating beans in context.
Spring beans can be initialized using applicationContext.xml or even programatically. In your case; you will need to remove configurations from xml and add into java program. You can get some idea from How to programmatically create bean definition with injected properties? . Other good links were also available on google.
I need to inject a Spring bean into a Seam context. Unless I declare the spring bean as a EJB, I cannot get it injected into other seam-managed components. But when I do this, all the spring injected fields are usless cause Seam creates new instances at run-time.
I also tried to add the <seam:component/> element to the spring bean definition and tried to inject it in the container with the #In("beanId") annotation in the target class but I always end up with a NullpointerException...
EDIT:
I read the online articles and did as they say. My spring component is also added to the seam context (I can tell, cause when I define one with the same ID in seam, it complains). Looks like #In is not picking up....
Have you read this chapter? It should tell you exactly what to do.
Raoul,
Although i do not use Seam along with Spring, chapter 15 of Seam In Action books talks about Spring integration. It is free and is updated.
You have said
I also tried to add the element to the spring bean definition and tried to inject it in the container with the #In("beanId")
Seam in Action book says
The EL expression used in the #In annotation, #{tournamentManager}, resolves to an equivalently named bean in the Spring container, courtesy of the delegating variable resolver
Do you have to use #In("#{beanId}") instead of #In("beanId"), do not ?
I have seen
By default, <seam:component/> will create a STATELESS Seam component with class and name provided in the bean definition.
<bean id="someSpringBean" class="SomeSpringBeanClass" scope="prototype">
<seam:component/>
</bean>
And
The scope attribute of <seam:component/> may be used if you wish the Spring bean to be
managed in a particular Seam scope. The Spring bean must be scoped to prototype if the
Seam scope specified is anything other than STATELESS.
Have you done as above ?
I have a project using Seam + Spring and I have to set #In(create=true) when I want to inject a Spring bean into my Seam component otherwise I get a NullPointerException, you should try it.
I got the same problem as yours. I followed strictly the "Chapter 27. Spring Framework integration" in seam ref. document. But my spring bean was never got injected to seam component. And finally, I found out I had the #BypassInterceptors in my seam component. By removing that annotation, my spring bean was successfully injected. Then I realized that, dependency injection is handled by seam BijectionInterceptor. Thus, the #BypassInterceptors will effectively bypass this filter :)
I've got a project using Jetspeed portal and Springframework 2.5.6 where I need a Jetspeed level service to be unique for each user logged in. This would be best done using Spring AOP and scope="session". The problem is, that these are behind the scenes beans that need to be running as soon as the session in initiated. It appears that Spring's AOP chooses a lazy load design and does not create or init the actual implementation until a method on the bean is called.
Is there a way to force Spring AOP to create the new bean as soon as the session object is created?
An excellent question. The easiest option that springs to mind (if you'll pardon the expression) is to wire your session-scoped bean into the controller that is invoked when the first request of the session comes in (and to do this, the controller would have to either be a session-scoped bean itself, or your bean would need to use aop:scoped-proxy).
If different controllers could be invoked at the start of the session, then you could wire the bean into a session-scoped interceptor instead, and configure your url mapping to pass the requests through the interceptor, ensuring that the bean is initialized right at the start of the session.
I can't really think of a more elegant way to do this. You could potentially create a custom HttpSessionListener which calls getBean("my-session-scoped-bean") on the app context when sessionCreated() is called, but that's a bit clunky.