I have a j2ee web application running on Spring framework. I want to implement logging using log4j and Spring's AOP. I was trying to find for references but I only get references which does not use log4j.
I had exactly the same configuration as what was on the link you gave. I have declared too a bean which where I want to implement logging. The beans id is ExecuteBLogic so I put below *BLogic
<bean name="methodLoggingInterceptor" class="org.developers.blog.spring.aop.logging.MethodLoggingInterceptor"/>
<bean name="proxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*BLogic</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>methodLoggingInterceptor</value>
</list>
</property>
</bean>
There are many examples that show how to log information using spring AOP. The fact that they are using System.out or java.util.logging should bother you - just replace these lines with log4j lines.
So, ontop of the class:
private static final Logger logger = Logger.getLogger(LoggingInterceptor.class);
and then instead of System.out.println(..):
logger.info(..);
Related
I'm trying to use Oval 1.84 for getting around some validation constraints without boilerplates. The validation works when I mark fields with #NotNull (javax.validation.constraint and net.sf.oval.validator).
But doesn't work in the case of implementing constarints to method and constructor parameters.
Parameter validation requires the use of some method invocation intercepting bytecode. OVal provides ready to use implementations for AspectJ and Spring AOP.
With AspectJ
How to use it with AspectJ is documented in detail at http://oval.sourceforge.net/userguide.html#programming-by-contract
With Spring AOP
The usage with Spring AOP is outlined in the test case at
https://svn.code.sf.net/p/oval/code/trunk/src/test/java/net/sf/oval/test/integration/spring/SpringAOPAllianceTest.java
In Spring you need to configure your beans for which you want to have method parameter validation, e.g.:
<bean id="myService" class="com.example.MyService" />
And an Invocation Interceptor:
<bean id="ovalGuardInterceptor" class="net.sf.oval.guard.GuardInterceptor" />
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="proxyTargetClass" value="false" />
<property name="interceptorNames">
<list>
<value>ovalGuardInterceptor</value>
</list>
</property>
<!-- the next line tells which beans you want to use validation for -->
<property name="beanNames" value="myService" />
</bean>
I'm using java 1.6 and spring 3.0.4, I want to realize a java functionality that
calculate new data values
update one-by-one the existing values on the database
If in any of this step there's an error I want to rollback the whole transaction and come back to the previous state.
I already realized all this pieces of code, I just want to put them together. How I can manage this with the existing spring values that are working with #Entity and #Column annotations?
Thanks!
Short answer: as you're using Spring, the easiest would be to use the transaction management, creating a service that represents this transaction unit and annotate the method with #Transactional
In practice, you need to configure a PlatformTransactionManager in your application. As you seem to use JPA, the JpaTransationManager seems like an obvious choice. To enable the processing of the #Transactional annotation, you can either use #EnableTransactionManagement or the <tx:annotation-driven/> namespace. Both are explained in the Javadoc of #EnableTransactionManagement
By default, a runtime exception thrown from that annotated method will manage a transaction rollback. If your code is using checked exceptions, you'll have to configure the rollbackFor attribute of the annotation.
There are more details and examples available in the documentation
For people that need the same configuration, here you can find how I solved this problem, integrating Hibernate with Spring.
<!-- session factory activate the transaction modules for the specified classes -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="configLocation" value="classpath:config-hibernate.xml" />
<property name="packagesToScan">
<list>
<!-- Additional packages required to be added if entities located elsewhere -->
<value>com.some.package.dao</value>
<value>com.some.package.model</value>
<value>com.some.package.SpecificClass</value>
</list>
</property>
<property name="mappingResources" ref="mappingResources"/>
<bean id="mappingResources" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<!-- here you can add your hibernate mapping query that you want to use on transaction -->
<value>config-hibernate-mapping.xml</value>
</list>
</property>
</bean>
<!-- This will activate transactional annotation -->
<tx:annotation-driven transaction-manager="transactionManager" />
#Service
#Transactional
public class SpecificClass {
// write your method, everyone of them will be transactional
// and there will be a commit in case of success or rollback in case of exception
}
I have a standalone jar that uses spring. The config in my spring xml uses placeholders of which I've been replacing when compiling with maven. Example spring config:
<bean id="foo" class="package.Foo">
<property name="host" value="${db.host}" />
</bean>
Instead of replacing ${db.host} using maven I'd like to pass in a properties file at runtime, e.g.
java -jar Application.jar productionDB.properties
This would allow me to switch the db host at runtime by passing in the production db properties file or the testing db properties file.
Is it possible to do this or are there any better ways of achieving the same goal?
You could specify your property file as a System Property, e.g.:
java -jar Application.jar -DappConfig=/path/to/productionDB.properties
Then you should be able to reference that in your application context:
<context:property-placeholder location="file:${appConfig}"/>
<bean id="foo" class="package.Foo">
<property name="host" value="${db.host}" />
</bean>
You could use a PropertyPlaceholderConfigurer to use a .properties file to pass in the required variables.
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:productionDB.properties</value>
</list>
</property>
</bean>
You can leave your bean declaration as is. The properties will be automatically taken from the productionDB.properties file.
There are a few options:
Set your resources via your container's JNDI and use Spring's <jee:jndi-lookup/>.
Use Spring's <context:property-placeholder location="classpath:/myProps.properties" />. I prefer this short-hand over the "full" bean definition because Spring will automatically use the correct implementation (PropertyPlaceholderConfigurer for Spring < 3.1, or PropertySourcesPlaceholderConfigurer for Spring 3.1+). Using this configuration, you would just drop the myProps.properties at the root of your classpath (${TOMCAT_HOME}/lib for example).
You can pass the values using the context:property-placeholder. So your setup would be something like:
<context:property-placeholder location="file://opt/db.properties"/>
Then when you are wiring up your Foo service, you can use the property names in your config, such as
<bean id="foo" class="package.Foo">
<property name="host" value="${db.host}" />
</bean>
Then just use the different set of files for each environmnet
See the spring docs for more details.
I am developing a Java desktop application and I am using Spring with it. Now I want to inject log4j to my classes using applicationContext.xml. My log4j properties file is placed in a source folder Resources/log4j.properties
During my search I found out that there are many way to it when its a web application but I found out no help regarding a desktop application.
I am using Apache commons interfaces in my source code and now I want to inject log4j dependency.
Kindly, help me out..
By default, Log4J will simply read its configuration from a "log4j.properties" file in the root of the class path. Since you placed your log4.properties file in the resources source folder, this should work.
If you do not want to store your log4j configuration in your class path then you can use something like this :
<bean id="log4jInitialization"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"
value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>myPropertiesFolder/log4j.xml</value>
</list>
</property>
</bean>
I have a PropertyPlaceholderConfigurer like this:
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath:assuredlabor/margarita-${runningMode}.properties</value>
</list>
</property>
</bean>
I would like to be able to specify my running mode in web.xml like this:
<context-param>
<param-name>runningMode</param-name>
<param-value>production</param-value>
</context-param>
So I put this bean ABOVE the 'main' property bean I described above:
<bean id="servletPropertyPlaceholderConfigurer" class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
</bean>
But that doesn't seem to work.
Is this possible with Spring? I am using version 2.5 right now.
I found this similar question:
PropertyPlaceholderConfigurer with Tomcat & ContextLoaderListener
But there is no discussion of the ServletContextPropertyPlaceholderConfigurer, so I think it is a legitimate question.
You can't do this in spring 2, without some custom coding I don't think, since one property placeholder cannot configure another.
You need to use spring 3 to get this out of the box. To accomplish this, you have to create a bean that somehow has the value you want, and use spring-el to reference that spring when setting up your property placeholder. There's a special bean for getting individual servlet context parameters as show below:
<bean id="runningMode" class="org.springframework.web.context.support.ServletContextAttributeFactoryBean">
<property name="attributeName" value="runningMode" />
</bean>
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath:assuredlabor/margarita-#{runningMode}.properties</value>
</list>
</property>
</bean>
And then you can just refer to any of the properties in the normal ${} syntax
From the source code:
Subclass of PropertyPlaceholderConfigurer that resolves placeholders as ServletContext init parameters (that is, web.xml context-param entries).
Can be combined with "locations" and/or "properties" values in addition to web.xml context-params. Alternatively, can be defined without local properties, to resolve all placeholders as web.xml context-params (or JVM system properties).
If a placeholder could not be resolved against the provided local properties within the application, this configurer will fall back to ServletContext parameters. Can also be configured to let ServletContext init parameters override local properties (contextOverride=true).
Optionally supports searching for ServletContext attributes: If turned on, an otherwise unresolvable placeholder will matched against the corresponding ServletContext attribute, using its stringified value if found. This can be used to feed dynamic values into Spring's placeholder resolution.
If not running within a WebApplicationContext (or any other context that is able to satisfy the ServletContextAware callback), this class will behave like the default PropertyPlaceholderConfigurer. This allows for keeping ServletContextPropertyPlaceholderConfigurer definitions in test suites.
As I understand it, that implies that you can use just a single configurer:
<bean id="propertyPlaceholderConfigurer" class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath:assuredlabor/margarita-${runningMode}.properties</value>
</list>
</property>
</bean>