How to bind a bean property to another one and observe changes in Spring Framework - spring

I'm wondering that if there is a way for binding a spring bean's property to another bean's property so if any change on binded property occurs in runtime, what i expect is referencing bean's property also changes. I'll explain more with a little code snippet.
<bean id="johnHome" class="example.Contact">
<property name="phone" value="5551333" />
</bean>
<bean id="johnWork" class="example.Contact">
<property name="phone">
<util:property-path path="johnHome.phone" />
</property>
</bean>
OK. This works at initial bean wiring but what i exactly want is to bind property so if the property changes at runtime the referencing bean also changes. If i should like to show with a metaphor it will seem like this.
<bean id="johnHome" class="example.Contact">
<property name="phone" value="5551333" />
</bean>
<bean id="johnWork" class="example.Contact">
<property name="phone">
<util:bind path="johnHome.phone" />
</property>
</bean>
Am i overloading the spring's concept too much or is this possible without a lot of tricks?
Thanks..

Simplest way - make that property a bean which is referenced by the two other beans, e.g. for a String value have a StringHolder class:
public class StringHolder {
private String value;
// setter and getter elided due to author's lazyness
}

The whole idea behind Spring is (was?) to keep a clean object-oriented design consisting of plain old java objects and use the spring framework to handle the tedious object creation. As for AOP, this should only handle cross-cutting concerns. I'm not at all convinced that this is one of those cases where AOP is a good idea. Your application relies on the behaviour of these phone numbers getting synced to each other, it's one of the main functionalities. As such, your design should reflect this.
Probably the most logical way to handle this specific problem is to make phone numbers their own class (which is also handy if you ever want to distinguish different types of phone numbers).
If you have a PhoneNumber object which takes the number as a constructor argument the mapping becomes trivial:
<bean id="johnFirstPhone" class="example.PhoneNumber">
<constructor-arg value="5551333" />
</bean>
<bean id="johnHome" class="example.Contact">
<property name="phone" ref="johnFirstPhone" />
</bean>
<bean id="johnWork" class="example.Contact">
<property name="phone" ref="johnFirstPhone" />
</bean>
Of course whether you'd map it like this in a static file is another matter, but the thing is in this situation you pretty clearly just need a reference/pointer.

I don't think what you're doing is possible in Spring 2.5. It may be possible in Spring 3, using the new expression syntax, but I don't think so.
Even if it were, it'd be confusing, I think. Better to stick your shared value into its own class and inject an instance of that class into the other beans that need to share it.

I can think of two possibilities.
One is (it is kind of a hack), if you don't have very many beans that need to be linked like the ones in your example, you could inject johnWork into the johnHome bean, and in johnHome.setPhone you could update the johnWork phone property, something like:
public class Contact {
private Contact myWorkContact;
private String phone;
public void setPhone(String phone) {
this.phone = phone;
if (this.myWorkContact != null) {
this.myWorkContact.setPhone(phone);
}
}
public void setWorkContact(Contact c) {
this.myWorkContact = c;
}
}
Or you could have HomeContact and WorkContact both extend a class Contact and do the same injection with that.
If you have tons and tons of beans that will need this (like if your application actually IS dealing with contact information), with AOP (you'll need AspectJ for the example given) I think you could do something like this (it will be a bit memory intensive if you get a ton of objects, but you can see how something like it would work):
Warning: this actually got complicated fast, but I'm pretty sure it would work after you worked out a few kinks
public class Contact {
...
private String phone;
private String name;
private Integer id;
public Contact(Integer id, String name, String phone) {
this.phone = phone;
this.name = name;
this.id = id;
}
public void setPhone(String phone) {
this.phone = phone.
}
//Other getters, setters, etc
...
}
#Aspect
public class ContactPhoneSynchronizer {
//there is probably a more efficient way to keep track of contact objects
//but right now i can't think of one, because for things like a tree, we need to
//be able to identify objects with the same name (John Smith), but that
//have different unique ids, since we only want one of each Contact object
//in this cache.
private List<Contact> contacts = Collections.synchronizedList(new ArrayList<Contact>());
/**
This method will execute every time someone makes a new Contact object.
If it already exists, return it from the cache in this.contacts. Otherwise,
proceed with the object construction and put that object in the cache.
**/
#Around("call(public Contact.new(Integer,String,String)) && args(id,name,phone)")
public Object cacheNewContact(ProceedingJoinPoint joinPoint, Integer id, String name, String phone) {
Contact contact = null;
for (Contact c : contacts) {
if (id.equals(c.getId()) {
contact = c;
break;
}
}
if (contact == null) {
contact = (Contact) joinPoint.proceed();
this.contacts.add(contact);
}
return contact;
}
/**This should execute every time a setPhone() method is executed on
a contact object. The method looks for all Contacts of the same
name in the cache and then sets their phone number to the one being passed
into the original target class.
Because objects are passed by reference until you do a reassociation,
calling c.setPhone on the object in the cache should update the actual
instance of the object in memory, so whoever has that reference will
get the updated information.
**/
#After("execution(example.Contact.setPhone(String) && args(phone)")
public void syncContact(JoinPoint joinPoint, String phone) {
Contact contact = joinPoint.getTarget();
for (Contact c : this.contacts) {
if (c.getName().equals(contact.getName()) {
c.setPhone(phone);
}
}
}
}
Again, there is probably 100 ways you could optimize this, since I'm typing it off the top of my head; that is, if you wanted to go this route in the first place. In theory it should work but I haven't tested it at all.
Anyway, Happy Springing!

Related

Primefaces dataTable with commandButton send multiple request to hibernate [duplicate]

Let's say I specify an outputText component like this:
<h:outputText value="#{ManagedBean.someProperty}"/>
If I print a log message when the getter for someProperty is called and load the page, it is trivial to notice that the getter is being called more than once per request (twice or three times is what happened in my case):
DEBUG 2010-01-18 23:31:40,104 (ManagedBean.java:13) - Getting some property
DEBUG 2010-01-18 23:31:40,104 (ManagedBean.java:13) - Getting some property
If the value of someProperty is expensive to calculate, this can potentially be a problem.
I googled a bit and figured this is a known issue. One workaround was to include a check and see if it had already been calculated:
private String someProperty;
public String getSomeProperty() {
if (this.someProperty == null) {
this.someProperty = this.calculatePropertyValue();
}
return this.someProperty;
}
The main problem with this is that you get loads of boilerplate code, not to mention private variables that you might not need.
What are the alternatives to this approach? Is there a way to achieve this without so much unnecessary code? Is there a way to stop JSF from behaving in this way?
Thanks for your input!
This is caused by the nature of deferred expressions #{} (note that "legacy" standard expressions ${} behave exactly the same when Facelets is used instead of JSP). The deferred expression is not immediately evaluated, but created as a ValueExpression object and the getter method behind the expression is executed everytime when the code calls ValueExpression#getValue().
This will normally be invoked one or two times per JSF request-response cycle, depending on whether the component is an input or output component (learn it here). However, this count can get up (much) higher when used in iterating JSF components (such as <h:dataTable> and <ui:repeat>), or here and there in a boolean expression like the rendered attribute. JSF (specifically, EL) won't cache the evaluated result of the EL expression at all as it may return different values on each call (for example, when it's dependent on the currently iterated datatable row).
Evaluating an EL expression and invoking a getter method is a very cheap operation, so you should generally not worry about this at all. However, the story changes when you're performing expensive DB/business logic in the getter method for some reason. This would be re-executed everytime!
Getter methods in JSF backing beans should be designed that way that they solely return the already-prepared property and nothing more, exactly as per the Javabeans specification. They should not do any expensive DB/business logic at all. For that the bean's #PostConstruct and/or (action)listener methods should be used. They are executed only once at some point of request-based JSF lifecycle and that's exactly what you want.
Here is a summary of all different right ways to preset/load a property.
public class Bean {
private SomeObject someProperty;
#PostConstruct
public void init() {
// In #PostConstruct (will be invoked immediately after construction and dependency/property injection).
someProperty = loadSomeProperty();
}
public void onload() {
// Or in GET action method (e.g. <f:viewAction action>).
someProperty = loadSomeProperty();
}
public void preRender(ComponentSystemEvent event) {
// Or in some SystemEvent method (e.g. <f:event type="preRenderView">).
someProperty = loadSomeProperty();
}
public void change(ValueChangeEvent event) {
// Or in some FacesEvent method (e.g. <h:inputXxx valueChangeListener>).
someProperty = loadSomeProperty();
}
public void ajaxListener(AjaxBehaviorEvent event) {
// Or in some BehaviorEvent method (e.g. <f:ajax listener>).
someProperty = loadSomeProperty();
}
public void actionListener(ActionEvent event) {
// Or in some ActionEvent method (e.g. <h:commandXxx actionListener>).
someProperty = loadSomeProperty();
}
public String submit() {
// Or in POST action method (e.g. <h:commandXxx action>).
someProperty = loadSomeProperty();
return "outcome";
}
public SomeObject getSomeProperty() {
// Just keep getter untouched. It isn't intented to do business logic!
return someProperty;
}
}
Note that you should not use bean's constructor or initialization block for the job because it may be invoked multiple times if you're using a bean management framework which uses proxies, such as CDI.
If there are for you really no other ways, due to some restrictive design requirements, then you should introduce lazy loading inside the getter method. I.e. if the property is null, then load and assign it to the property, else return it.
public SomeObject getSomeProperty() {
// If there are really no other ways, introduce lazy loading.
if (someProperty == null) {
someProperty = loadSomeProperty();
}
return someProperty;
}
This way the expensive DB/business logic won't unnecessarily be executed on every single getter call.
See also:
Why is the getter called so many times by the rendered attribute?
Invoke JSF managed bean action on page load
How and when should I load the model from database for h:dataTable
How to populate options of h:selectOneMenu from database?
Display dynamic image from database with p:graphicImage and StreamedContent
Defining and reusing an EL variable in JSF page
Measure the render time of a JSF view after a server request
With JSF 2.0 you can attach a listener to a system event
<h:outputText value="#{ManagedBean.someProperty}">
<f:event type="preRenderView" listener="#{ManagedBean.loadSomeProperty}" />
</h:outputText>
Alternatively you can enclose the JSF page in an f:view tag
<f:view>
<f:event type="preRenderView" listener="#{ManagedBean.loadSomeProperty}" />
.. jsf page here...
<f:view>
I have written an article about how to cache JSF beans getter with Spring AOP.
I create a simple MethodInterceptor which intercepts all methods annotated with a special annotation:
public class CacheAdvice implements MethodInterceptor {
private static Logger logger = LoggerFactory.getLogger(CacheAdvice.class);
#Autowired
private CacheService cacheService;
#Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
String key = methodInvocation.getThis() + methodInvocation.getMethod().getName();
String thread = Thread.currentThread().getName();
Object cachedValue = cacheService.getData(thread , key);
if (cachedValue == null){
cachedValue = methodInvocation.proceed();
cacheService.cacheData(thread , key , cachedValue);
logger.debug("Cache miss " + thread + " " + key);
}
else{
logger.debug("Cached hit " + thread + " " + key);
}
return cachedValue;
}
public CacheService getCacheService() {
return cacheService;
}
public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}
}
This interceptor is used in a spring configuration file:
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut">
<bean class="org.springframework.aop.support.annotation.AnnotationMatchingPointcut">
<constructor-arg index="0" name="classAnnotationType" type="java.lang.Class">
<null/>
</constructor-arg>
<constructor-arg index="1" value="com._4dconcept.docAdvance.jsfCache.annotation.Cacheable" name="methodAnnotationType" type="java.lang.Class"/>
</bean>
</property>
<property name="advice">
<bean class="com._4dconcept.docAdvance.jsfCache.CacheAdvice"/>
</property>
</bean>
Hope it will help!
Originally posted in PrimeFaces forum # http://forum.primefaces.org/viewtopic.php?f=3&t=29546
Recently, I have been obsessed evaluating the performance of my app, tuning JPA queries, replacing dynamic SQL queries with named queries, and just this morning, I recognized that a getter method was more of a HOT SPOT in Java Visual VM than the rest of my code (or majority of my code).
Getter method:
PageNavigationController.getGmapsAutoComplete()
Referenced by ui:include in in index.xhtml
Below, you will see that PageNavigationController.getGmapsAutoComplete() is a HOT SPOT (performance issue) in Java Visual VM. If you look further down, on the screen capture, you will see that getLazyModel(), PrimeFaces lazy datatable getter method, is a hot spot too, only when enduser is doing a lot of 'lazy datatable' type of stuff/operations/tasks in the app. :)
See (original) code below.
public Boolean getGmapsAutoComplete() {
switch (page) {
case "/orders/pf_Add.xhtml":
case "/orders/pf_Edit.xhtml":
case "/orders/pf_EditDriverVehicles.xhtml":
gmapsAutoComplete = true;
break;
default:
gmapsAutoComplete = false;
break;
}
return gmapsAutoComplete;
}
Referenced by the following in index.xhtml:
<h:head>
<ui:include src="#{pageNavigationController.gmapsAutoComplete ? '/head_gmapsAutoComplete.xhtml' : (pageNavigationController.gmaps ? '/head_gmaps.xhtml' : '/head_default.xhtml')}"/>
</h:head>
Solution: since this is a 'getter' method, move code and assign value to gmapsAutoComplete prior to method being called; see code below.
/*
* 2013-04-06 moved switch {...} to updateGmapsAutoComplete()
* because performance = 115ms (hot spot) while
* navigating through web app
*/
public Boolean getGmapsAutoComplete() {
return gmapsAutoComplete;
}
/*
* ALWAYS call this method after "page = ..."
*/
private void updateGmapsAutoComplete() {
switch (page) {
case "/orders/pf_Add.xhtml":
case "/orders/pf_Edit.xhtml":
case "/orders/pf_EditDriverVehicles.xhtml":
gmapsAutoComplete = true;
break;
default:
gmapsAutoComplete = false;
break;
}
}
Test results: PageNavigationController.getGmapsAutoComplete() is no longer a HOT SPOT in Java Visual VM (doesn't even show up anymore)
Sharing this topic, since many of the expert users have advised junior JSF developers to NOT add code in 'getter' methods. :)
If you are using CDI, you can use Producers methods.
It will be called many times, but the result of first call is cached in scope of the bean and is efficient for getters that are computing or initializing heavy objects!
See here, for more info.
You could probably use AOP to create some sort of Aspect that cached the results of our getters for a configurable amount of time. This would prevent you from needing to copy-and-paste boilerplate code in dozens of accessors.
If the value of someProperty is
expensive to calculate, this can
potentially be a problem.
This is what we call a premature optimization. In the rare case that a profiler tells you that the calculation of a property is so extraordinarily expensive that calling it three times rather than once has a significant performance impact, you add caching as you describe. But unless you do something really stupid like factoring primes or accessing a databse in a getter, your code most likely has a dozen worse inefficiencies in places you've never thought about.
I would also advice using such Framework as Primefaces instead of stock JSF, they address such issues before JSF team e. g in primefaces you can set partial submit. Otherwise BalusC has explained it well.
It still big problem in JSF. Fo example if you have a method isPermittedToBlaBla for security checks and in your view you have rendered="#{bean.isPermittedToBlaBla} then the method will be called multiple times.
The security check could be complicated e.g . LDAP query etc. So you must avoid that with
Boolean isAllowed = null ... if(isAllowed==null){...} return isAllowed?
and you must ensure within a session bean this per request.
Ich think JSF must implement here some extensions to avoid multiple calls (e.g annotation #Phase(RENDER_RESPONSE) calle this method only once after RENDER_RESPONSE phase...)

Spring 3 constructor injection anomaly: documentation vs. reality

Facts
Spring 3.2 documentation (http://docs.spring.io/spring/docs/3.2.9.RELEASE/spring-framework-reference/htmlsingle/#beans-constructor-injection):
When another bean is referenced, the type is known, and matching can occur (as was the case with the preceding example). When a simple type is used, such as true, Spring cannot determine the type of the value, and so cannot match by type without help.
package examples;
public class ExampleBean {
// No. of years to the calculate the Ultimate Answer
private int years;
// The Answer to Life, the Universe, and Everything
private String ultimateAnswer;
public ExampleBean(int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}
In the preceding scenario, the container can use type matching with simple types if you explicitly specify the type of the constructor argument using the type attribute. For example:
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg type="int" value="7500000"/>
<constructor-arg type="java.lang.String" value="42"/>
</bean>
My class:
package client;
public class Client {
private int id;
private String name;
public Client(int id, String name, String email) {
super();
this.id = id;
this.name = name;
}
}
bean definition:
<bean id="someClient" class="client.Client">
<constructor-arg value="5"></constructor-arg>
<constructor-arg value="5"></constructor-arg>
<constructor-arg value="5"></constructor-arg>
</bean>
Problem
I would have expected that the Spring IoC container will fail to create the bean someClient, since as stated above, it should be unable to address the types of constructor arguments specified. But, again, according to the docs a bit earlier:
If no potential ambiguity exists in the constructor arguments of a bean definition, then the order in which the constructor arguments are defined in a bean definition is the order in which those arguments are supplied to the appropriate constructor when the bean is being instantiated.
But alas, Spring registers the someClient bean effortlessly. This seems like a contradiction to me.
Question
So what is an ambiguous situation, according to Spring? The above example is clearly not ambiguous, Spring happily supplies the arguments in the order as they are defined in the bean definition. When is it really useful to use name/index attributes in the bean definition?
Consider this
<constructor-arg value="5"></constructor-arg>
You haven't specified a type, but a 5 can easily be converted to a String, or any of the numerical types. Similarly, and as an example,
<constructor-arg value="java.lang.String"></constructor-arg>
Spring can produce a String or a Class object as an argument. If a constructor was available for each of those types, then there would be ambiguity. If only one constructor exists, then the appropriate conversion strategy for that constructor will be used.
There's no ambiguity if there is only one constructor.
What is the point to confuse Spring? My unique explanation is testing or research.
But for the real life, if you see the same code three months later. I am sure you are not going be able to figure out what you are trying to do, is not clear and not readable your own code.
Avoid complicate the things. You can use the index attribute and the name attribute. I used to work with the second.
Now, how a strong suggestion, use annotations instead.
Think that you are able to share your code.

Call certain methods alone in a class using spring/pojo?

I am implementing a health check for my application.I have configured the classes for different logical systems in our application and have written methods which check for conditions across the environment like db count , logging errors , cpu process etc.
Now I have requirement where I have to check only certain conditions ie certain methods in the class according to the host.
What is the best way to access those methods via property file ? Please give your suggestions.
Thanks.
I don't like using reflection for this sort of thing. Its too easy for the property files to be changed and then the system starts generating funky error messages.
I prefer something straightforward like:
controlCheck.properties:
dbCount=true
logger=false
cpuProcess=true
Then the code is sort of like this (not real code):
Properties props = ... read property file
boolean isDbCount = getBoolean(props, "dbCount"); // returns false if prop not found
... repeat for all others ...
CheckUtilities.message("Version " + version); // Be sure status show version of this code.
if (isDbCount) {
CheckUtilities.checkDbCount(); // logs all statuses
}
if (... other properties one by one ...) {
... run the corresponding check ...
}
There are lots of ways to do it but this is simple and pretty much foolproof. All the configuration takes place in one properties file and all the code is in one place and easy for a Java programmer to comment out tests that are not relevant or to add new tests. If you add a new test, it doesn't automatically get run everywhere so you can roll it out on your own schedule and you can add a new test with a simple shell script, if you like that.
If its not running a particular test when you think it should, there's only two things to check:
Is it in the properties file?
Is the version of the code correct?
You can define different beans for every check you need:
<bean id="dbcountBean" class="DBCountHealtCheck" scope="prototype">
<!-- bean properties -->
</bean>
Then a bean for HealtCheck with operations bean injected:
<bean id="healtChecker" class="HealtChecker" scope="prototype">
<property name="activeChecker"><bean class="PropertiesFactoryBean>
<property name="location">file:path/to/file</property></bean>
</property>
<property name="dbCountCheck" ref="dbCountBean" />
<!-- other properties -->
</bean>
class HealtChecker {
private DBCountHealtCheck dbCountChecker;
private Properties activeChecker;
public void setDbcount(DBCountHealtCheck dbCountChecker) {
this.dbCountChecker = dbCountChecker;
}
public void setActiveChecker(Properties activeChecker) {
this.activeChecker = activeChecker;
}
public void check() {
if("true".equals(this.activeChecker.get("dbCount")) {
this.dbCountChecker.check();
}
}
If with this solution you can't reload file, in HealthChecker remove activeChecker a property public void setPropertiesLocation(URL propertiesLocation); let HealthChecker implements InitializingBean and load properties in afterPropertiesSet()

Inject Dynamic Values for the property in Spring

I am very new to Spring and while going through the DI topic through various sources (Book & Internet) I have seen the following pattern of defining bean configuration:
For example we have a class "SampleApp"
public class SampleApp
{
private int intValue;
private float floatValue;
public SampleApp(int value)
{
intValue = value;
}
public void setIntValue(int value)
{
intValue = value;
}
public void setFloatValue(float floatValue)
{
this.floatValue = floatValue;
}
}
Corresponding bean configuration is as follows:
<bean class="somepackage.SampleApp" id="samplebeanapp">
<constructor-arg value="15" />
<property value="0.5" name="floatValue"></property>
</bean>
We have been hard-coding the value here to 15 & 0.5.
Here are my questions :
Is it possible to pass those values as run time parameter with scope as prototype?
If yes, how can we do it? and please elaborate with some example.
Spring configuration files are processed at startup, and Spring singleton beans are instantiated too in that moment. They are not processed again during the application lifecycle, in normal conditions.
You can use such type of property injection to pass configuration values, while you can use injection of object references to determine the structure of your application.
To avoid hardcoding the values inside the XML files, you can extract them in property files using a PropertyPlaceholderConfigurer.
The principle is to program to interfaces as much as possible, so you don't tie yourself to any specific implementation. However, for the case you're thinking, you'll just pass the values at runtime.
Example: BeanA needs the services of DaoBean, but the DaoBean won't be instantiated by BeanA. It will be passed to BeanA through dependency injection and BeanA will only talk to a DaoInterface.
At this point if BeanA want to save 15 and 0.5, will call the methods with the actual values (or more commonly variables).
daoInterface.saveInt(15);
daoInterface.saveFloat(0.5);
I don't use dependency injection to pass the values in this case. Dependency injection is a great tool, but doesn't meant that it has to be used everywhere.

Spring 3.x PropertyOverrideConfigurer insists on using set, not constructor

Trying to use Spring PropertyOverrideConfigurer or some such subclass, to help
create the following bean:
public class Foo {
private final String name;
public Foo(String name) { this.name = name; }
public String getName() { return name; }
}
Suppose my bean definition is something like
<bean id="foo" class="Foo">
<constructor-arg name="name" value="abc">
</bean>
I've handed Spring a file foo.properties, in there it finds an entry
foo.name="def"
So the default name property for Foo bean is "abc", I want it overriden to be "def";
HOWEVER I do not want to have an explicit setName(String name) method hanging
off my Foo class, since despite what Spring thinks I consider this a terrible
idea in software development. I expect Spring to be able to pass the
overridden value as "def" to the constructor of Foo,
not call Foo later with setName("def").
I have not gotten this to work, is there a way? The only success I've had is
to add the method
public void setName(String name) { this.name = name; }
to the Foo class, which again I think is a terrible idea since it opens
up your class for unintentional side-effecting later.
Is there any hope? Can I modify the bean definition somewhere before
Spring creates Foo with the (wrong) "abc" name?
You can definitely do it. You xml should look somewhat like:
<bean id="foo" class="Foo">
<constructor-arg index="0" value="abc"/>
</bean>
Assuming that constructor has one parameter and "abc" is a value coming from your property file. In this case the setter is not needed.
More information is available in Spring documentation at http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-factory-collaborators

Resources