Conditions in Spring expression language(SpEL) used in bean definition - spring

As far SpEL is used in Spring 3.0,
I would like to ask, is it possible to do following(in bean definition .xml):
<c:choose>
<c:when test="#{prop=='a'}">
<bean class="BeanA"/>
</c:when>
<c:otherwise>
<bean class="BeanB"/>
</c:otherwise>
</c:choose>
Someth. like in jstl.
Thank you for help.

Environment profiles/Environment specific beans will be available in Spring 3.1 which should be released shortly - so you might want to wait for that.
There is no built in support for conditional beans in Spring 3.0. However, it could be achieved by using PropertyPlaceholderConfigurers and/or FactoryBeans.

There's no conditional mechanism for XML Spring bean defintion files.
However, maybe this would work:
<bean class="#{prop=='a' ? BeanA : BeanB}"/>
But even if this approach worked, it wouldn't be the most readable one. My suggestion would be to use different set of XML configuration files and pick them depending on some global settings. Naturally you would put all the common beans (i.e. these whose definition is always the same) in a separate file and have it always included.

it is not a question of using spel, but more of XML,afaik you can't do this in XML (but xslt)
the proper spring way for this scenario might be http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-class in combination with a "parent" interface for BeanA and BeanB
you could pass the parameter (system ? runtime specific ?) to the factory, which would create either BeanA or BeanB

Related

Single spring bean with two different ids in same xml(application context)

If we create a new another bean with different id in the same xml for the same class, will spring produce another singleton bean(in same ApplicationContext)?
As per my understanding there should be only one instance of the bean in single ApplicationContext.
Below example-
<bean id="bean1" class="com.myCompany.myPackage.MyClass" scope="singleton" />
<bean id="bean2" class="com.myCompany.myPackage.MyClass" scope="singleton" />
To keep it short: No, the singleton only says that you'll have: "one shared instance, which will be returned by all calls to getBean with the given id" (that's what the documentation states).
So, you can do any number of calls to application context and obtain "bean1" and you'll always get the same instance, but if you call by "bean2" id, you'll get another instance.
The "singleton" says that you'll have only one object. Now in a non-Spring application, you'll have it usually per JVM. But in spring application, let the framework manage this. So usually you'll want to define only one class like "MyClass" with a scope singleton.
When dependency management container (Spring in this case) manages singletons, it has a lot of advantages over the 'regular' singleton. Just to name a few:
Much easier to test
You always know when the object is created and when it becomes subject to garbage collector
No static code (the Spring driven singleton is just a regular bean with no statics)
But in general it's not directly related to your question.
I did have this same question just in a different context of Spring's singleton vs. Java's singleton and I found this answer provided by 'Dexter' in this link more subtle and easy to understand.
Also, this blog here provides a perfect example for the same which is backed by the official spring documentation for better-detailed understanding.
Hope these pointers help. Thanks.

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.

Autowiring byName or byType or constructor?

1)In Spring which autowiring in preferred?I am a beginner in learning springs so am not getting which ones to use frequently?Is it that the different types of autowiring have their own advantages and disadvantages?If yes then what?
2)From Springs in action
eg:
<bean id="saxophone"
class="com.springinaction.springidol.Saxophone"
primary="true" />
And all the others their primary is set false.So i can only use this bean for autowiring.So what if i need other beans to autowire which are of the same Instrument type since saxophone is of the Instrument type and that since saxophone is declared primary then how will others be preferred depending upon situations?
No autowiring have advantages or disadvantages. It solely depends upon you, which one to use or your project specification and architecture.
And for your particular example, you have to use byName autowiring.

Spring config and runtime separation

When using Spring it is rather cumbersome to incorporate runtime data in bean construction. While there are techniques to circumvent this separation, I have a feeling that it was put in place for a reason. My question is whether this is a known paradigm, and if there is any litterature discussing it. Personally I find that it has both advantages and drawbacks, depending on the dynamicity of the app.
You have at least five well known methods to pass runtime data to beans configuration:
Use ApplicationContextInitializer to add PropertySources to the Enviroment.
Use SPEL to inject dependencies.
Use FactoryBeans.
Use the factory-bean and factory-method attributes.
If you write the class that need the runtime data, you only need to inject the
collaborator that provide it.
For example
<bean id="requestAttributeReader" class="example.RequestAttributeReader" />
<bean id="requestInjectedBean" class="example.RequestInjectedBean" scope="request">
<property name="a" value="#{requestAttributeReader.a}" />
</bean>
Class RequestAttributeReader {
public String getA() {
return RequestContextHolder.getAttributes().getAttribute("a");
}
}
EDIT
The bean description files of an IoC container lets you to configure implementors on application beans. This is normally a static definition of the implementation classes that you want to use for a concrete configuration, so xml it's good for it.
If you need to choose an implementor based on runtime then you need to write code to choose them and then inform the container.
for example, using PropertySources and PropertyPlaceholderConfigurer:
String service = "example.NormalService";
if (BOSS_USERNAME.equals(System.getProperty("user.name")))
service = "example.BossService";
ctx.getEnvironment().getPropertySources().addFirst(new PropertiesPropertySource("service", service));
<bean id="service" class="${service}" />
The same could be done with a ServiceFactoryBean, a external ServiceFactory, SPEL and so on...
Maybe, you are interested on replacing implementations at runtime, ie changing the Service implementation in all beans that depends on when the container is already refreshed. (without destroy and refresh).
As far as I know, the framework don't provides a clear way to do it.
Sounds like you should look at spring binding, eg:
public String create(#Valid Market market, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
So this will take request params that match the fields in the Market object and set them in that object. It will also validated the params/object since there is the #Valid annotation.
This binding can be customised with PropertyEditors or Converters.
If the market object is annotated #Configurable, it can use #Autowired and #Value annotations to configure the bean when spring creates it.

Spring Framework (V2.5) - Using actionpath in ref attribute in a bean definition

I am a pretty newcomer for Spring Framework.
This is regarding referencing another bean using ref attribute.
I have a bean definition for an action class like below.
<bean name="/abc" class="com.example.actions.Action" scope="singleton">
<property name="businessLogic" ref="/pqr"/>
</bean>
I am trying to inject another bean into this bean using ref attribute (ie "/pqr").
<bean name="/pqr" class="com.example.businesslogic.PqrBL" scope="prototype" />
Now my question how normal is it to use name="/pqr" kind of a notation for a bean which is not a definition for some action class ? By convention is it an acceptable normal scenario ?
PS: please let me know if information provided is incomplete or the question is not clear.
Thanks
The Spring reference states that
The convention is to use the standard Java convention for instance field names when
naming beans. That is, bean names start with a lowercase letter, and are camel-cased from
then on. Examples of such names would be (without quotes) 'accountManager',
'accountService', 'userDao', 'loginController', and so forth.
It is not normal to use "/pqr" as a bean name but you can do it . I would prefer using more user friendly names to the beans than using a "path" .
Check here for the convention .

Resources