Spring in a JavaFX application - how to property handle controller as dependency? - spring

I have a JavaFX application that uses spring boot, exactly as described in this blog post:
http://www.greggbolinger.com/let-spring-be-your-javafx-controller-factory/
I am using the FXML loader overriding the controller factory to use spring.
The problem is that Spring loads the controller class marked as #Component on application start or later if marked with #Lazy, but keeps the bean in memory.
If I open a Stage, modify the data, close the stage and open it again, the data is still there (because the controller was kept by spring). It also gets in the way if I open two of the same Stage (window). It shares the same controller, so if I modify one, the other modifies too, and this is not the desired behavior.
How to I properly handle JavaFX controllers with spring?
Thanks!

Mark the controller as having prototype scope, so that a new instance is created on each request:
#Component
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Controller {
// ...
}

Related

Loading manually created object to spring context

I have an object created using a new operator. Is there a way, in Spring, to load this object in the Spring application context?
I did some research but could not find a working solution. Thanks in advance.
If you are creating an object after Spring application has started and you want to register it as bean with spring, you can do it. ie. run time only you will know how it will be created or that object is created by a external framework you don't have control over. I just can't remember the frameworks, there are frameworks that used this facility.
//Get hold of application context, you can autowire it
ConfigurableApplicationContext context;
ServiceX servicex = //This object was created outside spring framework.
//Register it with spring
context.getBeanFactory().registerSingleton("servicex", servicex);
//Above bean is now available as part of spring application context.
You can use Spring's #Configuration class and define #Bean method in there. In that method, create your custom new object and make sure you return that object.
#Bean
public YourType methodName() {
//code here..
return new YourType();
}
Put this into your #Configuration class and object returned by return new YourType(); will be registered into your Spring Context.

Spring - how to debug to find specific use of spring's auto-wiring or a request parameter?

Spring is auto-wiring in a request parameter - let's call it "bob".
I don't know where nor how it is doing this, so I cannot debug it. What spring specific code (using intellij, so I can at lest set a conditional) would be appropriate to find where the auto-wiring of the request parameter is happening, so I can work out what the system is doing?
I think I understood the question, so I will try to answer it as best as I can.
You are facing a dilemma of choosing between managing your instances, or letting Spring manage them. If you let Spring manage dependency injection, you will often face situations where you wish you had more fine control over the beans lifecycle.
By default, Spring beans are "singletons", which means that only one
instance of that object will be created, and every class that demands
a dependency injection of that object will receive the same instance.
The first step on beans lifecycle is its construction. You can setup a breakpoint to catch that moment on any method annotated with #PostConstruct. This article describes the need of running some code on bean initialization, and how it is solved by this annotation. For example:
public class AnyBean {
#PostConstruct
public void init(){
// any code or breakpoints inserted here will
// be run whenever an instance of this bean is created.
// if a singleton bean, only one instance is created and,
// only one #PostConstruct will be called.
// If a bean is a prototype bean, a new instance will be created
// for every dependency injection, and hence one #PostConstruct
// will be called for each.
}
}

Camel context properties from DB

Right now, I bootstrap Camel using Spring. Using Spring, I can point my Camel contexts to their respective properties files which are then injected at boot time. My issues is that I now want to move my properties from a file to a database, yet still be able to use the property placeholders as I was before. What's the best way to go about doing this?
I've noticed that there's a PropertiesResolver interface that I could implement, but I wouldn't know how to tell Camel about my implementation. Camel's documentation is very lacking in this area.
I also wouldn't be opposed to having Spring get the properties from the database for me, although I don't see that happening.
The PropertiesResolver was designed to help Camel to locate the properties files from OSGi bundle or normal class path.
If you want to setup your owner PropertiesResolver, you can try to use org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer.
You can inject your customer implementation of PropertiesResolver there.
I thought I'd update this with what I found to work. This probably isn't the best method way to do it, but it works and I didn't have to modify the Camel source code. Basically, I converted all of my classes from inheriting from RouteBuilder to inherit from GJKRouteBuilder (which inherits from RouteBuilder). Then in there, I did this:
public class GJKRouteBuilder extends RouteBuilder {
#Override
protected void checkInitialized() throws Exception {
//Get properties from CamelContext using getContext()
//Lookup properties from DB based on CamelContext
//Get the properties component from the context (or create one)
//call setOverrideProperties() on properties component
super.checkInitialized();
}
}
Again, probably not the best method, but it works. Now, any route that inherits from GJKRouteBuilder and has the proper values wired up through Spring will have the properties injected into the properties component as if they were coming right from a properties file.

How to inject a JSF bean into a spring bean

I'm working on a legacy JSF application which we are slowly porting over to Spring MVC. We are using Spring Security to control login information. After logging the user in, the JSF pages globally instantiate a session scoped bean that is used everywhere. I'd like to change the application so that we can go to a page that was developed with Spring MVC first.
One approach I tried was to convert the bean into a spring bean and have it injected into JSF, but unfortunately that turned out to require a lot of changes to the bean to make it possible. One possible hack I thought of is to add a special redirecting JSF page to initialize the JSF beans before sending the user to the Spring MVC page. That seems like quite a bit of a hack though so I'm looking for another solution.
Is there some other way that I can force the session scoped bean to be initialized before I go to my Spring pages so that I can just pull the bean out of session?
If you are using Spring MVC, you can make your "bean" a Model Attribute, then have it auto-loaded into session using a combination of annotations on the Controller, handler methods, and a method that creates an instance of your bean. Your controller would look something like this:
#Controller
#SessionAttributes({"myBean"})
#RequestMapping("/myPath")
public class MyController {
#RequestMapping("/myPath2")
public String myHandler(#ModelAttribute("myBean") MyBean myBean) {
// ...do stuff, return view
}
#ModelAttribute("myBean")
MyBean createMyBean() {
// Create and init an instance
return new MyBean();
}
}
You will get a MyBean magically created for you whenever there isn't one, and any time you update the Model (or ModelAndView) with "myBean", it will also get magically added to the Session.

Having some issues in InventoryController class?

These days i am learning spring by http://static.springsource.org.
I am facing some problem in this page http://static.springsource.org/docs/Spring-MVC-step-by-step/part4.html. i am not getting it clearly that when setProductManager method is called when InventoryController class is invoked. I know that this works as a front controller and when hello.jsp page is requested ,ModelAndView method is executed of InventoryController. but i want to know that when setProductManager method is called.
Any help would be appreciable.
Spring is an ioc container and in this particular example the dependency-injection is implemented using setters (setter injection). Basically the container takes care of supplying your bean (controller in this case) with necessary dependencies.
Back to your question: dependency injection is performed before your bean is ever used by the framework or any other beans requiring it. Furthermore, controllers are singletons. This means setProductManager is called before any request is handled by the controller - when the application is started. And because there is only one instance of the controller - it is called once.

Resources