Could I use Spring EL inside bean id attribute? - spring

Could I use SpEL inside the id attribute of a bean ?
e.g :
<bean id="#{T(com.om.m).PublicStaticFinalStringProperty}"...
This way it's not working, what should I change or it's not possible ?

Weird but possible (sample uses spring 3.1). Different versions working:
<?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: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/util http://www.springframework.org/schema/util/spring-util.xsd
">
<context:property-placeholder properties-ref="myProps"/>
<util:properties id="myProps" >
<prop key="x.y.z">possible</prop>
</util:properties>
<bean id="testBean" class="Bean">
<property name="value" value="weird"/>
</bean>
<bean id="${x.y.z}" class="Bean">
<property name="value" value="but"/>
</bean>
<bean id="#{testBean.value}" class="Bean">
<property name="value" value="${x.y.z}"/>
</bean>
</beans>
Bean.java
public class Bean implements InitializingBean {
String value;
public void setValue(String value) {
this.value = value;
}
public void afterPropertiesSet() throws Exception {
System.out.println(value);
}
}

Related

autowiring spring bean in camel processor

I am building OSGI bundle for running in Jboss Fuse 6.1 container. Project contains blueprint.xml (in src/main/resoureces/OSGI-INF/blueprint). It is content:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd
http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd"
>
<bean id="MyProcessor" class="com.test.MyProcessor" />
<camelContext trace="false" id="blueprintContext" xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="activemq:queue:paymentsqueue?username=admin&password=admin" id="NotificationRoute">
<description/>
</from>
<log message="The message contains ${body}"/>
<process ref="MyProcessor"/>
</route>
</camelContext>
</blueprint>
My goal is using spring beans in MyProcessor. This is code for MyProcessor:
public class MyProcessor implements Processor {
#Aurowired
private Sender sender;
#Override
public void process(Exchange x) throws Exception {
log.info("test: " +sender.getSenderId());
}
}
But it gives me nullpointerexception. What I am doing wrong?
This is content of my spring configuration file(i placed it in src/main/resoureces/META-INF/spring)
<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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.username"/>
<bean id="sender" class="com.username.Sender" scope="prototype">
<property name="senderId" value="sendername" />
<property name="password" value="senderpassword" />
</bean>
I think you have not declared the Processor MyProcessor as a bean in spring like
<bean id="myProcessor"
class="com.test.MyProcessor" />
then you can use it as
<process ref="myProcessor"/>
Also the
#Aurowired
private Sender sender;
should be #Autowired(This should be a typo but pointed it out.)

Spring #Transaction not rolling back on RuntimeException

I want to support rollback when an exception occurs in my code.
I use junit + datasource in Spring config file for testing and Glassfish 2.1 for the real code (using jndi datasource).
Here a sample of the code.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:test-web-spring-config.xml" })
public class PersistTest {
#Autowired
Transformer transformer;
#Before
public void setUp() throws Exception {
}
#After
public void tearDown() throws Exception {
}
#Test
#Transactional("transactionManagerTest")
//#Rollback(false)
// #Ignore
public void test() {
transformer.export();
}
}
#Component
public class Transformer {
#Autowired
ContextPersist context;
#Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void export(){
//code here
// persist here
context.persist();
// to test a rollback
throw new RuntimeException("testing rollback2");
}
}
#Component
public class ContextPersist {
#Autowired
#Qualifier(value = "dataSource")
DataSource dataSource;
// bulk insert
JdbcTemplate jdbcTemplate;
#Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void persist() {
jdbcTemplate = new JdbcTemplate(dataSource);
//.. here I insert data with jdbcTemplate.batchUpdate(....)
// to test a rollback
throw new RuntimeException("testing rollback1");
}
}
That code doesn't rollback.
If I use #Rollback(true) in my Junit, the transaction will rollback. But I need the same behavior outside a JUnit.
EDITED : (added the spring config)
My project contains a webapp (demo.war) and a jar for DAO+businessrules
In my webapp, I have my transformer.
I have a parent Spring config in this webapp, and a common spring config shared with others webapps.
Here the files.
demo.war
web-spring-config.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
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/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<context:component-scan base-package="com.test" />
<tx:annotation-driven />
<task:annotation-driven/>
<import resource="classpath:common-spring-config.xml" />
</beans>
DAO.jar
common-spring-config.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
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.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="com.test" />
<tx:annotation-driven />
<task:annotation-driven/>
<!-- Hibernate -->
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="demo.datasource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory" />
</bean>
<!-- datasource -->
<bean id="demo.datasource" class="org.springframework.jndi.JndiObjectFactoryBean"
lazy-init="true">
<property name="jndiName" value="jdbc/demo" />
</bean>
</beans>
your transaction manager is
org.springframework.orm.hibernate3.HibernateTransactionManager
but you use JdbcTemplate
the AOP is configured to auto begin/commit/rollback on hibernate operations.
jdbcTemplate would not participate in any transaction.
no transaction = no rollback.
its like connection.setAutoCommit(true);

Spring AOP - expression "&&" Not working while combining pointcuts

Aspect Class:
#Aspect
public class LoggingAspect {
#Before("e1() && e2()")
public void loggingAdvice(){
System.out.println("before execution of the method");
}
#Pointcut("execution(public String com.spring.Employee.getName())")
public void e1(){}
#Pointcut("execution(public String com.spring.Department.getName())")
public void e2(){}
}
Client Class:
public class AspectClient {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Employee emp = (Employee) context.getBean("employee");
System.out.println(emp.getEmpId());
System.out.println(emp.getName());
System.out.println(emp.getDepartment().getName());
}
**Config file:**
<?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: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.xsd">
<bean id= "employee" class="com.spring.Employee" autowire="byName">
<property name="empId" value="7329" />
<property name="name" value="Sagar" />
</bean>
<bean id= "department" class="com.spring.Department" >
<property name="name" value="ApplicationManagement" />
<property name="typeOfProjects" value="Maintenance" />
</bean>
<bean class="com.spring.LoggingAspect"/>
<aop:aspectj-autoproxy />
<context:annotation-config />
</beans>
Explanation:
#Before("e1() && e2()")
When I just call either e1() or e2() individually, it works but not both at same time.
I dont get any errors., Just the advices are not called.
I am using spring 3.2.3
AspectJ and AOP alliance jar files
Which is as expected. The pointcut never matches it will never match both the execution e1 and execution e2 on the same time. Instead of && you probably want || .
It basically is an if statement and both sides have to resolve to true a

Cannot Apply AOP in Glassfish

Hi need help in learniing basic spring .
i have a simple Aspect
#Aspect
public class HelloAspect {
static final Logger log = Logger.getLogger(HelloAspect.class .getClass().getName());
#Before("execution(* *.*(..))")
public void logBefore(JoinPoint joinPoint) {
log.info("The method " + joinPoint.getSignature().getName()+ "() begins with "+Arrays.toString(joinPoint.getArgs()));
}}
dispatcher-servlet.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:tx="http://www.springframework.org/schema/tx"
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-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema /tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<aop:aspectj-autoproxy />
<context:component-scan base-package="com"></context:component-scan>
<mvc:annotation-driven></mvc:annotation-driven>
<context:annotation-config></context:annotation-config>
<context:load-time-weaver/>
<bean class="com.abhi.aop.HelloAspect"/>
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
application-context.xml is
I have a simple entity from derby table and controller mapping
goal is to print logbefore logger before every method.
but i get nothing on server after deployment log.

Dependency Injection in Spring MVC

I would like to initialize my MessageSource field with Dependency Injection in Spring. This is what have so far:
package com.ucmas.cms.view;
#Component
public class PdfRevenueReportView extends AbstractPdfView {
...
#Autowired
private MessageSource messageSource;
...
}
mvc-dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="sec://www.springframework.org/schema/mvc"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<context:component-scan base-package="com.ucmas.cms.controller,com.ucmas.cms.view" />
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
...
<beans:bean class="org.springframework.web.servlet.view.XmlViewResolver">
<beans:property name="location" value="/WEB-INF/spring-pdf-views.xml" />
<beans:property name="order" value="0" />
</beans:bean>
</beans:beans>
I have defined my messageSource in root-context.xml
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
My controller classes work fine, however I am unable to inject the messageSource field in the PdfRevenueReportView class. What should I do to make the DI works ?
UPDATED
I define the view in xml 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="PdfRevenueSummary" class="com.ucmas.cms.view.PdfRevenueReportView" />
</beans>
Perhaps this is why the messageSource is always null ?
I got it working by updating my spring-pdf-views.xml into
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="PdfRevenueSummary" class="com.ucmas.cms.view.PdfRevenueReportView">
<property name="messageSource" ref="messageSource"/>
</bean>
</beans>
However this requires me to generate setter and getter for messageSource field and removing the #Autowired annotation.
In your dispatcher servlets configuration you need to create a bean for the message source.
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="directory/with/messagesource"/>
</bean>
Also ensure that the messages directory is on the classpath.
You are annotating messageSource with Autowired. This might not work when your bean messageSource whilst is an interface of MessageResource, is really the implementation ResourceBundleMessageSource.
I think your DI would have worked if you used #Resource instead as it is name based:
#Resource
private MessageSource messageSource;

Resources