When used with prototype scope ( or request scope in Web ), the EL are processed differently if they are set with @Value annotation, or by XML.
Code sample :
Code:public class BeanA { private Integer callOne = 0; private Integer callTwo = 0; public Integer getCallOne() { return ++callOne; } public Integer getCallTwo() { return ++callTwo; } }Code:public class BeanB { /** * Injected by EL Annotation */ private Integer callOne; /** * Injected by EL XML */ private Integer callTwo; public Integer getCallOne() { return callOne; } public Integer getCallTwo() { return callTwo; } @Value("#{beanA.callOne}") public void setCallOne(Integer callOne) { this.callOne = callOne; } public void setCallTwo(Integer callTwo) { this.callTwo = callTwo; } }Code:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <context:annotation-config/> <bean id="beanA" class="com.dexiabil.citrix.test.BeanA"></bean> <bean id="beanB" class="com.dexiabil.citrix.test.BeanB" scope="prototype"> <property name="callTwo" value="#{beanA.callTwo}"></property> </bean> </beans>
And the Test :
On the second call, with Annotation-Based EL the getter is not called a second time, but well with the XML Based configuration.Code:public class ExpressionTest { ApplicationContext context; @Before public void setUp() { context = new ClassPathXmlApplicationContext("ExpressionTest-context.xml", this.getClass()); } @Test public void testSameOneCall() { BeanB beanB = context.getBean("beanB", BeanB.class); assertEquals((Integer) 1, beanB.getCallOne()); assertEquals((Integer) 1, beanB.getCallTwo()); assertEquals(beanB.getCallOne(), beanB.getCallTwo()); // OK } @Test public void testSameTwoCall() { BeanB beanB = context.getBean("beanB", BeanB.class); assertEquals((Integer) 1, beanB.getCallOne()); assertEquals((Integer) 1, beanB.getCallTwo()); assertEquals(beanB.getCallOne(), beanB.getCallTwo()); beanB = context.getBean("beanB", BeanB.class); assertEquals((Integer) 2, beanB.getCallOne()); // Failed here, getCallOne equals 1, the method is not called again assertEquals((Integer) 2, beanB.getCallTwo()); // getCallTwo equals 2, the method is called assertEquals(beanB.getCallOne(), beanB.getCallTwo()); }
Is it normal to have different processing t?


Reply With Quote
