JSF 2 managed beans and their methods naming convention when used in EL expressions (in conjunction with Spring) - spring

As far as I know, standard JavaBeans convention for converting properties/class names is used in JSF EL, i.e. method pairs (get|is)Property + setProperty are converted to just property:
public class SomeComponent {
public String getAttribute() { ... }
public void setAttribute(String attribute) { ... }
}
<h:outputText value="#{comp.attribute}" />
The same goes for bean names (unless these names are directly specified in #ManagedBean annotation):
#ManagedBean
public class UsefulBean {
...
}
<h:outputText value="#{usefulBean.doSomething()}" />
This behavior is mostly documented. However, I couldn't manage to find anything about conversion conventions when bean or properties names are started with an acronym, something like
#ManagedBean
public class URLManagerBean {
}
<h:outputText value="#{...ManagerBean.doSomething()}" />
What should go instead of ellipsis in the previous snippet?
Surprisingly, but there is little to no information on the internet on this. Almost all examples of JSF managed beans usage use bean names without multiple adjacent capital letters in the beginning. In the few places I've managed to find it is suggested that bean names started with multiple capital letters should not be converted in any way, i.e. it would be URLManagerBean in the previous code snippet.
Unfortunately, we have a project where a lot of beans are named that way. And everywhere these beans are used they follow this weird, to the least extent, convention:
class URLManagerBean -> uRLManagerBean
That is, only the first letter of the acronym is decapitalized. The project seems to be working well, so this convention somehow works. But IntelliJ IDEA does not like this; it thinks that JSF beans really should be named like URLManagerBean unless I rename it explicitly through the annotation.
I tried changing usage of class URLManagerBean from uRLManagerBean to URLManagerBean, but apparently this does not work - those pages where I tried it stopped working.
Now I think that the reason behind such weird convention is that we're using Spring integration via SpringBeanFacesELResolver. However, this behavior is not documented anywhere.
Is there some explanation for this behavior?

Which #ManagedBean annotation are you using? The one from javax.faces.bean or javax.annotation?
In the first case Spring has nothing to do with it as it will be a JSF managed bean and will follow the conventions as specified by JSF.
The value of the name() attribute is taken to be the managed-bean-name. If the value of the name attribute is unspecified or is the empty String, the managed-bean-name is derived from taking the unqualified class name portion of the fully qualified class name and converting the first character to lower case. For example, if the ManagedBean annotation is on a class with the fully qualified class name com.example.Bean, and there is no name attribute on the annotation, the managed-bean-name is taken to be bean. The fully qualified class name of the class to which this annotation is attached is taken to be the managed-bean-class. Source: #ManagedBean javadocs
In the second case Spring is in the mix and then the behavior differs based on which spring version and/or configuration option you use. Using the AnnotationConfigApplicationContext the AnnotationBeanNameGenerator is used which follows the guidelines (and would result in 'URLManagerBean ' as a bean name). Using other means you might end up with the DefaultBeanNameGenerator which has a much simpler algorithm.
Simply said it might depend on which spring version and which annotation you use.
Links
#ManagedBean Java Documentation
Source for ManagedBeanConfigHandler which generates the beanname (reference implementation)

Related

Spring Boot application.properties appear unregistered when accessed from constructor

This is the code that I have:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
public Program() {
System.out.println(appTitle);
}
}
The application.properties has
app.title=The Program
The output is null insteaf of The Program.
So, what am I missing? I have tried several examples; none worked.
Since appTitle is an autowired field, it is not set until after the object is initially constructed. This is why the value is still null in your example. The bean construction process in this scenario is as follows:
The Program constructor is called, creating a new Program instance
The appTitle field is set on the newly constructed bean to ${app.title}
The ideal fix for this depends on your goals. If you truly need the value within the constructor, you can pass it in as an autowired constructor parameter. The value will then be available within the constructor:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
public Program(#Value("${app.title}") appTitle) {
System.out.println(appTitle);
}
}
If you don't need it in the constructor itself, but need it for the proper initialization of the bean, you could alternatively use the #javax.annotation.PostConstruct annotation to make use of it after the object's construction but before it is made available for use elsewhere:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
#PostConstruct
public void printAppTitle() {
System.out.println(appTitle);
}
}
Finally, if you don't need the value at construction time, but need it during the life of the bean, what you have will work; it just won't be available within the body of the constructor itself:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
}
Nothing wrong, just don't do it in a constructor...
Other answers on this question are written assuming the goal is creating a Spring-managed bean that uses the given property in its creation. However, based on your comments in another answer, it looks like the question you want answered is how to access an externalized property (one provided by #Value) within a no-argument constructor. This is based on your expectation that a Java inversion of control (IoC) container such as Spring should allow accessing externalized properties (and presumably other dependencies) within a no-argument constructor. That being the case, this answer will address the specific question of accessing the property within a no-argument constructor.
While there are certainly ways this goal could be achieved, none of them would be idiomatic usage of the Spring framework. As you discovered, autowired fields (i.e. fields initialized using setter injection) cannot be accessed within the constructor.
There are two parts to explaining why this is. First, why does it work the way it does, programmatically? Second, why was it designed the way it was?
The setter-based dependency injection section of the Spring docs addresses the first question:
Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.
In this case, it means that first the object is created using the no-argument constructor. Second, once the object is constructed, the appTitle is initialized on the constructed bean. Since the field isn't initialized until after the object is constructed, it will have its default value of null within the constructor.
The second question is why Spring is designed this way, rather than somehow having access to the property within the constructor. The constructor-based or setter-based DI? sidebar within the Spring documentation makes it clear that constructor arguments are in fact the idiomatic approach when dealing with mandatory dependencies in general.
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. [...]
The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. [...]
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. [...]
A property needed to construct the object certainly would be categorized as a mandatory dependency. Therefore, idiomatic Spring usage would be to pass in this required value in the constructor.
So in summary, trying to access an application property within a no-argument constructor is not supported by the Spring framework, and in fact runs contrary to the recommended use of the framework.

How to register bean programatically in Quarkus?

I am trying to find a way how to programatically create bean in quarkus DI, but without success. Is it possible in this framework? It seems that BeanManager does not implement the needed method yet.
First, we should clarify what "programatically create bean" exactly means.
But first of all, we should define what "bean" means. In CDI, we talk about beans in two meanings:
Component metadata - this one describes the component attributes and how a component instance is created; the SPI is javax.enterprise.inject.spi.Bean
Component instance - the real instance used in application; in the spec we call it "contextual reference".
The metadata is usually derived from the application classes. Such metadata are "backed by a class". By "backed by a class" I mean all the kinds described in the spec. That is class beans, producer methods and producer fields.
Now, if you want to programatically obtain a component instance (option 2), you can:
Inject javax.enterprise.inject.Instance; see for example the Weld docs
Make use of CDI.current().select(Foo.class).get()
Make use of quarkus-specific Arc.container().instance(Foo.class).get()
However, if you want to add/register a component metadata that is not backed by a class (option 2), you need to add an extension that makes use of quarkus-specific SPIs, such as BeanRegistrar.
If you are looking for Quarkus equivalent of Spring #Configuration then you want "bean producer" (as mentioned in comments above)
Here is an example(koltin) of how to manually register a clock:
import java.time.Clock
import javax.enterprise.context.ApplicationScoped
import javax.enterprise.inject.Produces
#ApplicationScoped
class AppConfig {
#Produces
#ApplicationScoped
fun utcClock(): Clock {
return Clock.systemUTC()
}
}
#Produces is actually not required if method is already annotated with #ApplicationScoped
#ApplicationScoped at class level of AppConfig is also not required
Although, I find those extra annotations useful, especially if are used to Spring.
You can inject your beans using Instance:
#Inject
public TestExecutorService(final ManagedExecutor managedExecutor,
final Instance<YourTask> YourTask) {
this.managedExecutor = managedExecutor;
this.YourTask= YourTask;
}
And if you need to create more than one Instance you can use the managed executor:
tasks.forEach(task -> managedExecutor.submit(task::execute));
Keep in mind that depending on the way you start the bean you may need to destroy it and only the "creator class" has its reference, meaning you have to create and destroy the bean in the same classe (you can use something like events to handle that).
For more information please check: CDI Documentation

Custom Annotations in spring

In my project we have set up something like below
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,ElementType.ANNOTATION_TYPE, ElementType.PARAMETER})
#Inherited
#Documented
#Qualifier(“MessageConverterQualifier”)
public #interface MessageConverterRef {}
Above Is used at many places in CoreConfig files (annotation based loading)
#Bean
#MessageConverterRef
public DocumentToABCResponseMessageConverter
documentToABCResponseMessageConverter() {
return new DocumentToABCResponseMessageConverter();
}
#Bean
#MessageConverterRef
public StringToABCResponseMessageConverter stringToABCResponseMessageConverter(
StringToDomBasedMessageConverter stringToDomBasedMessageConverter) {
return new StringToABCResponseMessageConverter(stringToDomBasedMessageConverter);
}
I am not able to understand what is the need of MessageConvertoerRef custom annotation here.
This custom annotation is used at now of places while initializing the beans using #Bean.
Request you to let me know what does it mean and what difference is it making .
This is an elegant solution to ensure compile-time safety for autowiring a set of beans by using the same qualifier. If you look at your custom annotation #MessageConverterRef you will see that the only truly meaningful annotation it is decorated with is:
#Qualifier(“MessageConverterQualifier”))
Use case: you happen to have a set of beans serving the same purpose (like having converters for different types, like you do) it would be really convinient to annotate all of them with the same Spring Qualifier (in your case MessageConverterQualifier), so that they can be all autowired into a list.
The next step is to recognize that having a set of beans scattered across your project that should be annotated with the same qualifier name is not enterily safe, neither the most elegant solution. Defining your own annotation (#MessageConverterRef) once, and reuse it everywhere it is needed reduces the chance of of error (typos) and at the same time increases readability and provides a cleaner code.
For more info on the topic I suggest reading the corresponding Spring doc, especially this part:
Qualifiers also apply to typed collections (as discussed above): e.g. to Set. In such a case, all matching beans according to the declared qualifiers are going to be injected as a collection. This implies that qualifiers do not have to be unique; they rather simply constitute filtering criteria. For example, there could be multiple MovieCatalog beans defined with the same qualifier value "action"; all of which would be injected into a Set annotated with #Qualifier("action").

Custom annotation like #Value

I need to create a means to add a custom annotation like
#Value("${my.property}")
However, in my case I need to get the value from a database rather then a properties file.
Basically I would like to create a bean on container startup that reads in property name value pairs from a database and can then inject these into fields belonging to other beans.
Approach #1:
One way is to create an Aspect, with a point-cut expression that matches any method having this annotation.
Your aspect will then:
Read the property value in the annotation
Look up the required value an inject it into the class.
AOP Kickstart
Here's a guide to getting started with AOP in Spring
http://www.tutorialspoint.com/spring/aop_with_spring.htm
Joinpoint matching
Here's a reference that describes how to create a join-point that matches on annotations: http://eclipse.org/aspectj/doc/next/adk15notebook/annotations-pointcuts-and-advice.html
Approach #2:
Another way is to use a BeanFactoryPostProcessor - this is essentially how a PropertyPlaceholderConfigurer works.
It will look at your bean definitions, and fetch the underlying class.
It will then check for the annotation in the class, using reflection.
It will update the bean definition to include injecting the property as per the value in the annotation.
. . actually I think approach #2 sounds more like what you want - all of the processing happens on "start-up". . . (In actual fact your modifying the bean recipes even before startup). . whereas if you used AOP, you'd be intercepting method invocations, which might be too late for you?
Namespace Handler
If you wanted you could even create your own Spring namespace handler to turn on your post processor in a terse way. Eg:
<myApp:injectFromDb />
as an alternative to:
<bean class="MyDatabaseLookupProcessorImpl etc, etc. />
Update: Approach #3
As of Spring 3.1 there's also the PropertySourcesPlaceholderConfigurer, that will provide most of the plumbing for you, so you can achieve this with less code.
Alternatively you should be able to configure kind of properties repository bean and then use it in SpEL directly in #Value annotation.
Let's say you'd have bean called propertiesRepository in your context that implements following interface:
interface PropertiesRepository {
String getProperty(String propertyName);
}
then on bean where you want to inject values you can use following expression
#Value("#{propertiesRepository.getProperty('my.property')}")
String myProperty;
You can use #Value annotation by injecting database configuration in application environment itself.
I know this is an old question but I didn't find an exact solution. So documenting it here.
I have already answered the same on different forum.
Please refer to this answer for exact solution to your problem.

Autowired.. more than one?

I am using
<context:component-scan base-package="com.package.dao"/> (Spring 3)
and in my controllers with #Autowired will retrieve automatically the DAO I need. That's perfect and works.
The problem is when I need more than one DAO manager.
How can I do?
I tried with #Qualifier but I am not sure about the name of the dao-manager. className doesn't work
someone can help me?
Thank you!
See in the spring documentation:
#Autowired is fundamentally about type-driven injection with optional semantic qualifiers. This means that qualifier values, even when using the bean name fallback, always have narrowing semantics within the set of type matches; they do not semantically express a reference to a unique bean id
...
If you intend to express annotation-driven injection by name, do not primarily use #Autowired - even if is technically capable of referring to a bean name through #Qualifier values. Instead, prefer the JSR-250 #Resource annotation which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
Use #Resource instead, see here.

Resources