I have a sample code in which I am trying to convert application-context.xml to Spring annotated Java class. How to add constructor-arg with proper annotations here. Could you please help me sort this.
application-context.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:util="http://www.springframework.org/schema/util"
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/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:component-scan base-package="myproject"/>
<!-- Define the SOAP version used by the WSDL -->
<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>
</property>
</bean>
<!-- The location of the generated Java files -->
<oxm:jaxb2-marshaller id="marshaller" contextPath="myproject.wsdl.currency"/>
<!-- Configure Spring Web Services -->
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/>
<property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
<property name="defaultUri" value="http://www.webservicex.net/CurrencyConvertor.asmx?WSDL"/>
</bean>
<bean id="example" class="org.project.Example"/>
I have created Config.class as below.
#Configuration
public class AppConfig {
#Bean(name="soapMessageFactory")
public SaajSoapMessageFactory getSoapMsgFactory() {
SaajSoapMessageFactory soapFactory = new SaajSoapMessageFactory();
soapFactory.setSoapVersion(SoapVersion.11);
return soapFactory;
}
#Bean(name="webServiceTemplate")
public WebServiceTemplate getWsTemplate(Marshaller marshaller, Unmarshaller unmarshaller) {
WebServiceTemplate wsTemplate = new WebServiceTemplate();
//how to configure the constructor-arg here
wsTemplate.setMarshaller(marshaller);
wsTemplate.setUnMarshaller(unmarshaller);
wsTemplate.setDefaultUri(http://www.webservicex.net/CurrencyConvertor.asmx?WSDL);
return wsTemplate;
}
#Bean(name="example")
public Example getExample() {
return new ExampleImpl();
}
This should work...
#Bean(name="soapMessageFactory")
public SaajSoapMessageFactory getSoapMsgFactory() {
SaajSoapMessageFactory soapFactory = new SaajSoapMessageFactory();
soapFactory.setSoapVersion(SoapVersion.11);
return soapFactory;
}
#Bean(name="webServiceTemplate")
public WebServiceTemplate getWsTemplate(SaajSoapMessageFactory soapFactory, Marshaller marshaller, Unmarshaller unmarshaller) {
WebServiceTemplate wsTemplate = new WebServiceTemplate(soapFactory);
wsTemplate.setMarshaller(marshaller);
wsTemplate.setUnMarshaller(unmarshaller);
wsTemplate.setDefaultUri(http://www.webservicex.net/CurrencyConvertor.asmx?WSDL);
return wsTemplate;
}
When you specify any dependecy in #Bean method, spring will search for that bean in its context.
Since SaajSoapMessageFactory is locally created and doesn't have any other dependency, you could just call it locally like this
WebServiceTemplate wsTemplate = new WebServiceTemplate(getSoapMsgFactory());
Related
I am trying to call mainframe stored procedure using TempStatusClass in this class I am loading status-dao.xml which has the datasource defined and stored procedure defined. When I try to call this I am getting following exception org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testProcedure' defined in class path resource [status-dao.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities).
Not sure what is causing this. Any help is highly appreciated.
#TempStatusClass
public class TempStatusClass implements DataServiceIF{
#Override
public Object execute(Object param) throws AppException {
StatusUpdateVO input = new StatusUpdateVO();
input.setShipment("X3328332842");
Map dataMap = null;
String springConfig = "status-dao.xml";
ApplicationContext context =new ClassPathXmlApplicationContext(springConfig);
StatusUpdateImpl statusUpdate = (StatusUpdateImpl) context.getBean("statusUpdateDao");
try {
dataMap = statusUpdate.getData(input);
} catch (StatusUpdateDAOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return dataMap;
}
}
XML
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<context:component-scan base-package="com.ops.test.test.*" />
<!-- Step 1: Define the data source -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MAINEFRAME" />
</bean>
<!-- Step 2: Define JDBC template -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Step 3: Define Stored Procedures -->
<bean id="testProcedure"
class="com.ops.test.test.sp.StatusUpdateStoredProcedure">
<constructor-arg>
<ref bean="jdbcTemplate" />
</constructor-arg>
<constructor-arg value="D472J00.N472RPTL" />
</bean>
<!-- Step 4: Define the DAOs -->
<bean id="statusUpdateDao"
class="com.ops.test.test.dao.impl.StatusUpdateImpl">
<property name="dataSource" ref="dataSource" />
<property name="procedure" ref="testProcedure" />
</bean>
</beans>
Impl
public class StatusUpdateImpl extends JdbcDaoSupport implements StatusUpdateDao{
/** The data source. */
private DataSource dataSource;
/** The stored procedure. */
private StatusUpdateDao storedProcedure;
/** The jdbc template object. */
#Autowired
private JdbcTemplate jdbcTemplateObject;
public StatusUpdateImpl()
{
}
#Autowired
public StatusUpdateImpl(DataSource dataSource) {
setDataSource(dataSource);
JdbcTemplate jdbcTemplate = getJdbcTemplate();
}
public void setStoredProcedure(StatusUpdateDao storedProcedure)
{
this.storedProcedure = storedProcedure;
}
public Map getData(Object input) throws StatusUpdateDAOException {
Map data = storedProcedure.getData(input);
return data;
}
}
Are you using spring-data-commons RC1 version? I have the same problem and it started with version bump of this dependency. I created an issue on spring's jira as well:
https://jira.spring.io/browse/DATASOLR-348
I'm trying to get Memcache working in Spring.
I've setup a local Memcached server using Docker and Kitematic:
I can access the Memcached server using telnet: telnet 192.168.99.100 32780 and then run stats or stats items (which only prints out END if the cache is empty);
My pom.xml:
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>simple-spring-memcached</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>spring-cache</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>xmemcached-provider</artifactId>
<version>3.6.0</version>
</dependency>
In my applicationContext.xml I have the following:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
...
<import resource="cacheContext.xml" />
...
In cacheContext.xml my config is as follow:
<?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:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<aop:aspectj-autoproxy/>
<cache:annotation-driven/>
<context:component-scan base-package="com.google.code.ssm"/>
<context:component-scan base-package="com.mycee.application"/>
<bean id="cacheBase" class="com.google.code.ssm.aop.CacheBase"/>
<bean id="readThroughSingleCache" class="com.google.code.ssm.aop.ReadThroughSingleCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="readThroughMultiCache" class="com.google.code.ssm.aop.ReadThroughMultiCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="readThroughAssignCache" class="com.google.code.ssm.aop.ReadThroughAssignCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="updateSingleCache" class="com.google.code.ssm.aop.UpdateSingleCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="updateMultiCache" class="com.google.code.ssm.aop.UpdateMultiCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="updateAssignCache" class="com.google.code.ssm.aop.UpdateAssignCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="invalidateSingleCache" class="com.google.code.ssm.aop.InvalidateSingleCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="invalidateMultiCache" class="com.google.code.ssm.aop.InvalidateMultiCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="invalidateAssignCache" class="com.google.code.ssm.aop.InvalidateAssignCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="incrementCounterInCache" class="com.google.code.ssm.aop.counter.IncrementCounterInCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="decrementCounterInCache" class="com.google.code.ssm.aop.counter.DecrementCounterInCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="readCounterFromCache" class="com.google.code.ssm.aop.counter.ReadCounterFromCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean id="updateCounterInCache" class="com.google.code.ssm.aop.counter.UpdateCounterInCacheAdvice">
<property name="cacheBase" ref="cacheBase"/>
</bean>
<bean name="cacheManager" class="com.google.code.ssm.spring.SSMCacheManager">
<property name="caches">
<set>
<bean class="com.google.code.ssm.spring.SSMCache">
<constructor-arg name="cache" index="0" ref="defaultCache"/>
<constructor-arg name="expiration" index="1" value="300"/>
<constructor-arg name="allowClear" index="2" value="false"/>
</bean>
</set>
</property>
</bean>
<bean name="defaultCache" class="com.google.code.ssm.CacheFactory" depends-on="cacheBase">
<property name="cacheName" value="defaultCache"/>
<property name="cacheClientFactory">
<bean class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl"/>
</property>
<property name="addressProvider">
<bean class="com.google.code.ssm.config.DefaultAddressProvider">
<property name="address" value="localhost:11211"/>
</bean>
</property>
<property name="configuration">
<bean class="com.google.code.ssm.providers.CacheConfiguration">
<property name="consistentHashing" value="true"/>
</bean>
</property>
</bean>
</beans>
I've created three different methods, each using different caching mechanisms:
#Component("cacheEndpoint")
public class CacheClass {
#Autowired
SSMCacheManager cache;
public String getDateTime1(String anything) {
SSMCache c = cache.getCache("defaultCache");
String s = c.get(anything, String.class);
if (s != null) {
return s;
}
Date d = new Date();
String response = d.toString() + " - " + d.getTime();
c.put(anything, response);
return response;
}
#Cacheable("defaultCache")
public String getDateTime2(String anything) {
Date d = new Date();
String response = d.toString() + " - " + d.getTime();
return response;
}
#ReadThroughSingleCache(namespace = "defaultCache", expiration = 15000)
public String getDateTime3(String anything) {
Date d = new Date();
String response = d.toString() + " - " + d.getTime();
return response;
}
}
To access it I do:
#Autowired
CacheClass c;
...
// caches perfectly
c.getDateTime1("test");
// doesn't do any caching
c.getDateTime2("test");
// doesn't do any caching
c.getDateTime3("test");
After placing runtime exceptions in getDateTime2 and getDateTime3, it was established that the interceptors aren't being invoked.
Any idea what could be the cause of #Cachable and #ReadThroughSingleCache not doing their interception magic?
Update based on Matjaž Pečan's response:
CacheClass Interface:
public interface CacheClass {
public String getDateTime1(String anything);
public String getDateTime2(String anything);
public String getDateTime3(String anything);
}
CacheClass Implementation:
#Component("cacheEndpoint")
public class CacheClassImpl implements CacheClass {
#Autowired
SSMCacheManager cache;
public String getDateTime1(String anything) {
SSMCache c = cache.getCache("defaultCache");
String s = c.get(anything, String.class);
if (s != null) {
return s;
}
Date d = new Date();
String response = d.toString() + " - " + d.getTime();
c.put(anything, response);
return response;
}
#Cacheable("defaultCache")
public String getDateTime2(String anything) {
Date d = new Date();
String response = d.toString() + " - " + d.getTime();
return response;
}
#ReadThroughSingleCache(namespace = "defaultCache", expiration = 15000)
public String getDateTime3(String anything) {
Date d = new Date();
String response = d.toString() + " - " + d.getTime();
return response;
}
}
SOAP Endpoint where I'm testing the cache:
#Endpoint
public class PingEndpoint {
#Autowired
CacheClass c;
#ResponsePayload
#PayloadRoot(localPart = "PingRequest", namespace = "http://www.mycee.com/Application")
public PingResponse doPing(#RequestPayload PingRequest request) {
// caches perfectly
System.out.println(c.getDateTime1("test"));
// doesn't do any caching
System.out.println(c.getDateTime2("test"));
// doesn't do any caching
System.out.println(c.getDateTime3("test"));
}
}
cacheContext.xml:
<?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:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<aop:aspectj-autoproxy proxy-target-class="true"/>
<cache:annotation-driven/>
...
There is an error in SSM 3.6.0, please downgrade to 3.5.0 to solve the issue or try to add
depends-on="cacheBase"
to defaultCache bean definition.
Update 1
Self invocations don't work. A call won't be intercepted and result won't be cached if a invocation is through this object. Make sure that method defined in a bean is invoked from another Spring bean.
Update 2
For SSM method has to be annotated as below:
#ReadThroughSingleCache(namespace = "defaultCache", expiration = 15000)
public String getDateTime3(#ParameterValueKeyProvider String anything) {
...
}
Still interceptors for some reasons aren't triggered.
Spring proxying mechanisms differ depending on which implementation is used.
The default is AspectJ which requires interfaces (proxy-by-interface) and those interfaces will then be implemented by the actual proxy wrapped around your bean. Since your bean is only a class and does not have an interface, it is not proxied with AspectJ.
There are two possible solutions:
Implement an interface for CacheClass and use that interface in wiring to other beans
Use CGLib proxying (you will need to add a runtime dependency on CGLib) and add proxy-target-class in your aspectj-proxy element:
<aop:aspectj-autoproxy proxy-target-class="true"/>
I want to record execution time of my service method.
I think AOP is a easy way to do, so I wrote an Aspect:
#Aspect
public class ServiceLogAdviceAspect {
private static Logger LOG = LoggerFactory.getLogger(ServiceLogAdviceAspect.class);
#Around("execution(* com.j1.**.service.*(..))")
public Object doBasicProfilingTime(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
Object target = joinPoint.getTarget();
long start = System.currentTimeMillis();
Object retVal = joinPoint.proceed();
long end = System.currentTimeMillis();
LOG.error(String.format("Invoke [%s$%s] Takes %d ms", target.getClass().getCanonicalName(), methodName, (end - start)));
return retVal;
}
}
and Spring config:
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-autowire="byName">
<aop:aspectj-autoproxy/>
<bean id="logAdviceAspect"
class="com.j1.soa.common.aspect.ServiceLogAdviceAspect"></bean>
</beans>
But when I invoke the method
public ServiceMessage<GoodsDetailDto> getGoodDetail(GoodsDetailDto goodsDetailDto)
I get neither error output nor into the breakpoint.
EDIT
getGoodDetail is defined in class
com.j1.soa.resource.item.service.GoodsDetailServiceImpl
And I am calling it using Hessian RPC,
First defined spring bean of Remote Service in application-context-rpc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="goodsDetailService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="http://api.soa.item.j1.com/hessian/goodsDetailService" />
<property name="serviceInterface" value="com.j1.soa.resource.item.api.GoodsDetailService" />
<property name="readTimeout" value="6000"/>
</bean>
</beans>
Then defined it in client
#Autowired
private GoodsDetailService goodsDetailService;
And using it
GoodsDetailDto goodsDetailDto = new GoodsDetailDto();
goodsDetailDto.setGoodsId(NumericUtil.parseLong(goodsId));
goodsDetailDto.setProductId(NumericUtil.parseInt(productId));
goodsDetailDto.setSiteType(SiteType.MOBILE);
ServiceMessage<GoodsDetailDto> detailResult = goodsDetailService
.getGoodDetail(goodsDetailDto);
You should include logAdviceAspect in <aop:aspectj-autoproxy/>
<aop:aspectj-autoproxy>
<aop:include name="logAdviceAspect"/>
</aop:aspectj-autoproxy>
I was using spring to create objects through beans. Now I tried to use aop to create the same object and I get $Proxy cannot be cast to SaleRoom exception.
the previous xml was:
<?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:aop="http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
xmlns:context="http://www.springframework.org/schema/context/spring-context-2.5.xsd"
xmlns:flow="http://www.springframework.org/schema/webflow-config/spring-webflow-config- 1.0.xsd"
xmlns:jm s="http://www.springframework.org/schema/jms/spring-jms-2.5.xsd"
xmlns:jee="http://www.springframework.org/schema/jee/spring-jee-2.5.xsd"
xmlns:lang="http://www.springframework.org/schema/lang/spring-lang-2.5.xsd"
xmlns:osgi="http://www.springframework.org/schema/osgi/spring-osgi.xsd"
xmlns:tx="http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
xmlns:util="http://www.springframework.org/schema/util/spring-util-2.5.xsd"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/aop/spring-aop-2.5.xsd/spring-spring-aop-2.5.xsd-2.5.xsd
http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/context/spring-context-2.5.xsd/spring-spring-context-2.5.xsd-2.5.xsd
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd/spring-spring-webflow-config-1.0.xsd-2.5.xsd
http://www.springframework.org/schema/jms/spring-jms-2.5.xsd http://www.springframework.org/schema/jms/spring-jms-2.5.xsd/spring-spring-jms-2.5.xsd-2.5.xsd
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/jee/spring-jee-2.5.xsd/spring-spring-jee-2.5.xsd-2.5.xsd
http://www.springframework.org/schema/lang/spring-lang-2.5.xsd http://www.springframework.org/schema/lang/spring-lang-2.5.xsd/spring-spring-lang-2.5.xsd-2.5.xsd
http://www.springframework.org/schema/osgi/spring-osgi.xsd http://www.springframework.org/schema/osgi/spring-osgi.xsd/spring-spring-osgi.xsd-2.5.xsd
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/tx/spring-tx-2.5.xsd/spring-spring-tx-2.5.xsd-2.5.xsd
http://www.springframework.org/schema/util/spring-util-2.5.xsd http://www.springframework.org/schema/util/spring-util-2.5.xsd/spring-spring-util-2.5.xsd-2.5.xsd
">
<bean id="sale01" class="application.common.entities.BidRoom">
<property name="itemId" value="0001"/>
<property name="lifeTime" value="15"/>
</bean>
</beans>
And I used the following code to create the sales:
ApplicationContext context = new FileSystemXmlApplicationContext(SalesManager.getSalesSourceFile());
SaleRoom saleRoom;
List<String> salesNames = new LinkedList<String>();
List<SaleRoom> allSales = new LinkedList<SaleRoom>();
// Get all sales id's for beans
NodeList salesNodeList = salesDoc.getElementsByTagName("bean");
for (int i = 0; i < salesNodeList.getLength(); i++) {
Node nNode = salesNodeList.item(i);
salesNames.add(((Element) nNode).getAttribute("id").toString());
}
for (String saleName : salesNames) {
if(saleName.contains("sale")) {
saleRoom = (SaleRoom) context.getBean(saleName);
allSales.add(saleRoom);
}
}
return allSales;
This is the new xml:
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:aspectj-autoproxy>
<aop:include name="logSettersCalls"/>
</aop:aspectj-autoproxy>
<bean id="logSettersCalls" class="application.logging.aop.LogSettersCalls"/>
<bean id="sale01" class="application.common.entities.BidRoom">
<constructor-arg index="0" type="int" value="0001"/>
<constructor-arg index="1" type="int" value="15"/>
</bean>
</beans>
The Aspect logging class:
#Aspect
public class LogSettersCalls {
#Pointcut("execution(void set*(*))")
public void setMethod() {}
#Before("setMethod()")
public void logSetterCall(JoinPoint theJoinPoint) {
String methodName = theJoinPoint.getSignature().getName();
Object newValue = theJoinPoint.getArgs()[0];
Object theObject = theJoinPoint.getTarget();
System.out.println("The method " + methodName + " is called on object "
+ theObject + " with the value " + newValue);
}
}
I'm using the same code for creating the beans via aop. and I get
Exception in thread "main" java.lang.ClassCastException: $Proxy11 cannot be cast to application.common.entities.SaleRoom
The line that throws the exception:
saleRoom = (SaleRoom) context.getBean(saleName);
Any help will be appreciated. Thanks.
Does your SaleRoom class implement some interface? If yes, then you should use interface and not class in you code:
ISaleRoom saleRoom = (ISaleRoom) context.getBean(saleName);
Because if your bean implements some interface then Spring by default will create proxy based on this interface.
Here is a good article about proxy creation in Spring.
Also you can change proxying mechanism for Spring AOP if you want to create proxy for target class. This is described here in reference documentation.
I am using Spring 3.1 as standalone app.
I have some wierd situation and I guess I am missing something.
I have class which has method that I have exposed via JMX console.
that method is invoking a method via bean.
that bean I am initializing in advaned.
the wierd thing that after i am invoking the method via the jmx console the bean instance turn to be null.
Thats the JMX bean which is exposed:
public class TriggerBean implements IJmxTriggerBean
{
static Logger logger = Logger.getLogger(TriggerBean.class);
FeedListenerBean fe = null;
public void start()
{
try
{
// init();
PropertyConfigurator.configure(FixGWConstants.LOG4J_PATH);
ApplicationContext context = new ClassPathXmlApplicationContext(FixGWConstants.APPLICATION_CONTEXT_XML);
fe = (FeedListenerBean) context.getBean("FeedListenerBean");
doTheListen();
}
catch (Throwable t)
{
logger.error(t);
System.out.println(t);
}
}
//thats the method being exposed by jmx. pay attention that fe object has been initialized before by the start()
public void doTheListen()
{
fe.listen();
}
private void init()
{
Resource resource = new ClassPathResource(System.getProperty("user.dir") + "//config.properties");
try
{
Properties props = PropertiesLoaderUtils.loadProperties(resource);
String log4jPath = props.getProperty("LOG4J_PATH");
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am testing it via standalone:
public static void main(String[] args) throws Exception
{
protected TriggerBean trigger = new Trigger();
trigger.start();
}
applicationContext.xml:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- Must for auto wiring
<context:annotation-config />
-->
<context:component-scan base-package="com.fixgw.beans">
</context:component-scan>
<!-- start a JMX Server -->
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean" />
<bean id="FeedListenerBean" class="com.fixgw.beans.FeedListenerBean">
</bean>
<bean id="TriggerBean" class="com.fixgw.test.TriggerBean">
</bean>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="Server:name=HttpAdaptor">
<bean class="mx4j.tools.adaptor.http.HttpAdaptor">
<property name="port" value="8000" />
<property name="host" value="0.0.0.0" />
<property name="processor">
<bean class="mx4j.tools.adaptor.http.XSLTProcessor" />
</property>
</bean>
</entry>
<entry key="bean:name=TriggerBean" value-ref="TriggerBean" />
</map>
</property>
<property name="listeners">
<list>
<!--
let the HttpAdapter be started after it is registered in the
MBeanServer
-->
<bean class="com.fixgw.jmx.HttpAdaptorMgr">
<property name="mbeanServer" ref="mbeanServer" />
</bean>
</list>
</property>
</bean>
</beans>
When I first using start() the object fe is doing great.
but after invoking doTheListen( via JMX the object fe remind null(although it has already been initialized before)
any idea?
thanks,
ray.