Spring constructor injection with FXML - spring

I have searched for the answer, but i could not found too much.
What i have found: http://steveonjava.com/javafx-in-spring-day-2/
That is a good post about how to use spring for controllers, but it say that you cannot use constructor injection. That would not be so big pain, it is just not so clean for me.
The issue come up when i would like to use custom controls (or custom components). Custom controls are created by javafx so that will not be in spring context.
The issue is that with the given solution only the controllers will be created by spring. I have found a possible way that can be done. thanks to https://www.javacodegeeks.com/2012/04/fxml-custom-components-using.html articel. But i would like to generalize that solution. So the plan is to write my custom BuilderFactory and Builder implementations, which is required a lot of reflection.
What do you think about this approach?
Every idea is welcome

You can certainly use a BuilderFactory to do this. The code is not too bad at all, because the default builder factory is implemented in public API as JavaFXBuilderFactory. Thus you can simply delegate to that if there is no bean of the appropriate type in the application context.
Basically:
private Parent loadFXML(ApplicationContext applicationContext, URL fxmlLocation)
throws IOException {
FXMLLoader loader = new FXMLLoader(fxmlLocation);
// load controllers from application context:
loader.setControllerFactory(applicationContext::getBean);
// load controls from application context, where available:
loader.setBuilderFactory(new BuilderFactory() {
JavaFXBuilderFactory defaultFactory = new JavaFXBuilderFactory();
#Override
public javafx.util.Builder<?> getBuilder(Class<?> type) {
String[] beanNames = applicationContext.getBeanNamesForType(type);
if (beanNames.length == 1) {
return new javafx.util.Builder<Object>() {
#Override
public Object build() {
return applicationContext.getBean(beanNames[0]);
}
};
} else {
return defaultFactory.getBuilder(type) ;
}
}
});
return loader.load();
}

Related

Interceptor on a class method belonging to External Dependency

We have an Aspect in our code that had been PointCut on Hibernate class.
Our Aspect class looks something like this:
#PointCut("(execution(* *.getQueryString(..))" + "|| execution(* *.getQuery(..)))" + "&& (target(org.hibernate.engine.NamedSQLQueryDefinition))")
public void aroundNamedSQLQueryDefinitionGetQuery() {
}
#Around("aroundNamedSQLQueryDefinitionGetQuery")
public String addExtraFilter(ProceedingJoinPoint pjp) throws Exception {
//Logic to add extra filter to the Query.
}
Now we are trying to migrate this code to Quarkus. We have replaced Aspects with Interceptors which were present on code belonging to our modules.
But how do we add Interceptors on Hibernate classes?
Is there an alternate way to achieve this?
A Quarkus extension would allow you to manipulate the Hibernate classes (or your own classes).
To scaffold a basic extension,
mvn io.quarkus.platform:quarkus-maven-plugin:2.10.1.Final:create-extension -N \
-DgroupId=org.you \
-DextensionId=aspectorama
Then, in the [whatever]Processor class that gets created, you could add an AnnotationTransformerBuildItem
#BuildStep
AnnotationsTransformerBuildItem transform() {
return new AnnotationsTransformerBuildItem(new AnnotationsTransformer() {
public boolean appliesTo(org.jboss.jandex.AnnotationTarget.Kind kind) {
return kind == org.jboss.jandex.AnnotationTarget.Kind.METHOD;
}
public void transform(TransformationContext context) {
if ("org.hibernate.engine.NamedSQLQueryDefinition".equals(context.getTarget().asMethod().declaringClass().name()) && ("getQueryString").equals(context.getTarget().asMethod().name()) {
context.transform().add(YourAnnotation.class).done();
}
}
});
}
(I haven't tested that, and I may not have quite the method names you intended. I only did getQueryString not getQuery... but it shows the idea.)
You may also need to tell Quarkus about your interceptor if it's not in the main application codebase:
/**
* Makes the interceptor as a bean so we can access it.
*/
#BuildStep
void beans(BuildProducer<AdditionalBeanBuildItem> producer) {
producer.produce(AdditionalBeanBuildItem.unremovableOf(YourInterceptor.class));
producer.produce(AdditionalBeanBuildItem.unremovableOf(OtherExtraBean.class));
}
It may be that the annotation route isn't the best for your use case, and you could make the changes you needed more directly. It's worth browsing all the Quarkus build items, which are kind of like a library of built-in extension capabilities. For example, you can use #Record to create bytecode.

Spring - Injection of beans using Builder pattern

Context
An application that utilizes Spring 4.1.7. All configurations are in XML files (not using annotations) and I rather keep it that way (but I can change the ways things are done if I must).
Problem
I have created a new class that comes with a builder class.
Now I'd like to inject other beans into this new class. I can probably use lookup-methods and similar solutions to do that and then use the new class's builder in the caller beans to create an instance. However, I rather an instance of this new class to be injected to its caller beans then they creating one through the builder. This is where I'm not sure how I can do that. For example, this looks like an Abstract Factory to me, but I don't know how I can pass those parameters (which are passed to the builder) at runtime to the Abstract Factory and subsequently the factories it builds.
Some code snippets to make the question clearer:
public final class Processor {
private final StatusEnum newStatus;
private final Long timeOut;
// I'd like this to be be injected by Spring through its setter (below)
private DaoBean daoInstance;
private Processor() {
this.newStatus = null;
this.timeOut = null;
}
private Processor(Builder builder) {
this.newStatus = builder.getNewStatus();
this.timeOut = builder.getTimeOut();
}
// To be called by Spring
public void setDaoInstance(DaoBean instance) {
this.daoInstance = instance;
}
public void updateDatabase() {
daoInstance.update(newStatus, timeOut);
}
// Builder class
public static final class Builder {
private StatusEnum newStatus;
private Long timeOut;
// lots of other fields
public Long getTimeOut() {
return this.timeOut;
}
public StatusEnum getNewStatus() {
return this.newStatus;
}
public Builder withTimeOut(Long timeOut) {
this.timeOut = timeOut;
return this;
}
public Builder withNewStatus(StatusEnum newStatus) {
this.newStatus = newStatus;
return this;
}
public Processor build() {
return new Processor(this);
}
}
}
I'd like an instance of "DaoBean" to be injected to the "Processor" class. But to do that, Processor will have to be a bean or otherwise I have to utilize something like lookup-methods. On the other hand, wherever I want to use processor, I have to do something like this:
new Processor.Builder()
.withTimeOut(1000L)
.withNewStatus(StatusEnum.UPDATED)
.build()
.updateDatabase();
Instead of this, I wonder if I can make the Processor a bean that Spring can inject to its callers whilst maintaining its immutability. An instance of DaoBean can then be injected to the Processor by Spring. That way I'd be able to segregate the wiring code and the business logic.
It's worth mentioning that the Builder has a lot more than 2 fields and not all of them have to be set. This is why I thought an abstract factory is the way to go (building instances of the Processor in different ways).
One solution, while keeping the builder, would probably be to simply making the Builder itself a Spring bean...
This allows something like this..
#Autowired
private Builder builder;
public void someMethod() {
Result = builder.withX(...).doSomething();
}
This way, your Result object is immutable, can be created via a nice builder and the builder can inject the Spring bean (dao, in your case) into it without anyone even noticing that it's there.
And the only thing that changes is, that you don't create the builder yourself, but let Spring create it for you...
#Component
#Scope("prototype") // normally a good idea
public static class Builder {
#Autowired
private DaoBean dao;
// your logic here
}
(Same works with JavaConfig or XML config, if you don't want to scan.)
Especially with many combinations, I prefer a builder pattern, since a factory would need complex method signatures. Of course, the builder has the disadvantage that you cannot check at compile time if a given combination of attribute types is at least theoretically acceptable. Ok, you could simulate that with various builders, but that would probably be overkill.

Spring prototype following prototype design pattern

Spring provides bean scope as "Prototype". Means whenever bean is required in application, Spring container will create a fresh/new instance of bean.
Does is follow prototype design pattern also?
Does it create object only once and in subsequent request calls clone() method on created object to create new object?
Also if someone can provide example of prototype in JDK, Spring, Hibernate or any J2EE framework.
No spring does not use cloning to create prototype scoped instances.
Below is the code snippet taken from AbstractBeanFactory.doGetBean() function:
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
#Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
The createBean method call boils down to below code:
BeanUtils.instantiateClass(constructorToUse);
Spring does not use the Prototype Pattern, it uses reflection.
Plus, in order to use clone() it would have to subclass somehow a bean, because clone() is protected, so it does not use clone() either.
Here is a code fragment from
org.springframework.beans.factory.support.SimpleInstantiationStrategy
where you can see the use of java.lang.reflect.Constructor and java.lang.Class reflection method:
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
if (beanDefinition.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (beanDefinition.constructorArgumentLock) {
constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
...
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
...
}
...
}
...
}
So the term prototype is used to suggest that at every call to getBean, you'll get a new instance with the same properties. This is more than a simple call to a constructor however, because you'll get a bean with all dependencies wired and other properties set, so in a sense it is a prototype. Or at least it fits the concept very well.
I have not dug into Spring source code, but I think Beans with prototype scope in Spring are not created using clone() method because it is not mandatory to implement the Cloneable interface for those beans.
Moreover, suppose it is creating them using clone(). It would then be dangerous if someone is expecting deep copy instead of shallow copy.
You can always test it and find the answer.
No. Spring scopes such as prototype or singletone do not follow strictly design patterns. The naming of scopes was used to intuitively suggest behavior container provides.
This way you can have a "singleton" pattern within the container and create another object outside of the container. Similarly "prototype" pattern does not have to implement "clone" functionality.
You may want to look into this link as well: Singleton design pattern vs Singleton beans in Spring container
More elaborate explanations here:
https://springframework.guru/gang-of-four-design-patterns/prototype-pattern/

Is it possible to have multiple dependency resolvers in ASP.NET MVC 3?

Is it possible to have more than one dependency resolver in ASP.NET MVC 3 (similar to the case of ModelBinders and Providers)?
There is one scenario that I could think of where having multiple 'containers' or 'resolvers' is useful and that is multi-tenancy. With multi tenancy you run multiple customers (organizations, with their own set of users) in the same web application, and dynamically switch based on the login, request info, or domain info.
Still, DependencyResolver.Current is -as Darin noted- static, so there's nothing you can (or should do about this). However, you could hide multiple containers behind a single IDependencyResolver abstraction and return an implementation based on some criteria. It might look like this:
public class MultiTenantDependencyResolver
: IDependencyResolver
{
Func<int> tenantIdSelector,;
IDictionary<int, IDependencyResolver> tenantResolvers;
public MultiTenantDependencyResolver(
Func<int> tenantIdSelector,
IDictionary<int, IDependencyResolver> tenantResolvers)
{
this.tenantIdSelector = tenantIdSelector;
this.tenantResolvers= tenantResolvers;
}
private IDependencyResolver CurrentResolver
{
get { return this.tenantResolvers[tenantIdSelector()]; }
}
public object GetService(Type serviceType)
{
return this.CurrentResolver.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.CurrentResolver.GetAllInstances(serviceType);
}
}
The following code snippet shows the usage of this MultiTenantDependencyResolver:
var tenantResolvers = new Dictionary<int, IDependencyResolver>
{
{ Tenants.AbcId, BuildResolver(RegisterForTenantAbc) },
{ Tenants.KlmId, BuildResolver(RegisterForTenantKlm) },
{ Tenants.XyzId, BuildResolver(RegisterForTenantXyz) },
};
var multiTenantResolver = new MultiTenantResolver(
() => GetTenantIdFromUrl(), tenantResolvers);
DependencyResolver.SetResolver(multiTenantResolver);
private static int GetTenantIdFromUrl()
{
// TODO: return tenant id
}
private static IDependencyResolver BuildResolver(
Action<IKernel> tenantSpecificRegistrations)
{
var kernel = new Kernel();
// TODO: Tenant agnostic registrations. For instance
kernel.Bind<ITimeProvider>().To<SystemTimeProvider>();
tenantSpecificRegistrations(kernel);
return new NinjectDependencyResolver(kernel);
}
private static void RegisterForTenantAbc(IKernel kernel)
{
// TODO: regisrations for ABC tenant. For instance
kernel.Bind<ILogger>().To<AbcTenantLogger>();
}
Is it possible to have more than one dependency resolver in ASP.NET
MVC 3 (similar to the case of ModelBinders and Providers)?
No, this isn't possible. The DependencyResolver.Current is a static property that could be assigned only one resolver. This being said having more than one dependency resolver in an application hardly makes any sense. The idea is that all your dependencies are managed by a dependency injection framework such as Unity, Ninject or StructureMap. You would then have a custom dependency resolver wrapping your DI framework of choice that will be used by ASP.NET MVC to inject dependencies in various objects of the execution pipeline.
You are comparing it with model binders in your question but this comparison is unfair because a model binder is related to a specific type that it is designed to bind. Basically you could have many custom model binders for multiple view models.
You also seem to have mentioned some providers in your question but unfortunately you haven't beeen very specific so it's a bit harder to comment on this one.

Why the need of a specific Spring FXML Loader

I am looking at this example: Building Applications in JavaFX 2.0 and they show a custom SpringFxmlLoader:
import java.io.IOException;
import java.io.InputStream;
import javafx.fxml.FXMLLoader;
import org.springframework.context.ApplicationContext;
public class SpringFxmlLoader
{
private ApplicationContext context;
public SpringFxmlLoader(ApplicationContext context)
{
this.context = context;
}
public Object load(String url, Class<?> controllerClass) throws IOException
{
InputStream fxmlStream = null;
try
{
fxmlStream = controllerClass.getResourceAsStream(url);
Object instance = context.getBean(controllerClass);
FXMLLoader loader = new FXMLLoader();
loader.getNamespace().put("controller", instance);
return loader.load(fxmlStream);
}
finally
{
if (fxmlStream != null)
{
fxmlStream.close();
}
}
}
}`
Why does one need to create a specific spring FXML Loader? I mean, even with a simple fxml loader, when you load a fxml like this:
AnchorPane page = (AnchorPane) FXMLLoader.load(TabePaneGraph.class.getResource("Sample.fxml")); the Sample Controller is called anyways and any initialization is still done. I am trying to understand the motivation behind this specific custom SpringFxmlLoader implementation.
There are multiple ways to skin a cat. I'm guessing the motivation to use spring in that article is because many web developers would be familiar with it. It also might make it look more like an alternative to a Java EE application. Which it is, but not because you can use spring with it.
You don't need any dependency injection framework to develop with JavaFX, in fact we need to look carefully at our dependencies because they will add to download time if you are expecting users to download your application.
There are (at least) 2 ways, how to specify a controller:
declare the controller class in the FXML file: note that you specify
the class not the instance here. The FXMLoader will create a new
instance.
pass an existing instance (e.g. "this" or as here a bean instantiated with Spring) as the controller to the FXMLLoader
loader.getNamespace().put("controller", instance);
I'm not sure about this part, but I think it can be replaced with setController() in the latest JavaFX version.

Resources