Reputation: 1
I have built an application to test injecting log information (Entering and Exiting) around classes. I have built it using spring and used the following example for building it.
http://static.springsource.org/spring/docs/2.5.5/reference/aop.html#aop-aj-ltw
It works great now but I have 2 issues:
Below I have included all code and xml that is used. As I said all is working fine except the 2 issues above. Please assist me.
app.java
package se.jpab.application;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
@Service
public class App
{
public static void main( String[] args )
{
ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "spring.xml" });
Client client = (Client) appContext.getBean("client");
Location clientLocation = (Location) appContext.getBean("location");
// Set all values
clientLocation.setAdress1("Adress 1");
clientLocation.setAdress2("Adress 2");
clientLocation.setBox("N/A");
clientLocation.setCity("City of Dallas");
client.setName("John Doe");
client.setUrl("http://www.url.com");
client.setLocation(clientLocation);
// Print out all values
System.out.println(client.getName());
System.out.println(client.getUrl());
System.out.println(client.getLocation().getAdress1());
System.out.println(client.getLocation().getAdress2() + " " + client.getLocation().getCity());
}
}
Client.java package se.jpab.application;
import org.springframework.stereotype.Service;
@Service
public class Client {
String name;
String url;
Location location;
//Constructors
public Client(String custName, String custUrl, Location custLocation){
name = custName;
url = custUrl;
location = custLocation;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public Client(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
printThis(name);
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public void printThis(String inStr) {
System.out.println("PRIVAT METOD");
System.out.println("Inkommand sträng --> " + inStr);
}
}
Location.java
package se.jpab.application;
import org.springframework.stereotype.Service;
@Service
public class Location {
String city;
String adress1;
String adress2;
String box;
//Constructors
public Location (String city, String adress1, String adress2, String box){
this.city = city;
this.adress1 = adress1;
this.adress2 = adress2;
this.box = box;
}
public Location (){
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getAdress1() {
return adress1;
}
public void setAdress1(String adress1) {
this.adress1 = adress1;
}
public String getAdress2() {
return adress2;
}
public void setAdress2(String adress2) {
this.adress2 = adress2;
}
public String getBox() {
return box;
}
public void setBox(String box) {
this.box = box;
}
}
aop.xml
<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options=" -showWeaveInfo">
<!-- only weave classes in our application-specific packages -->
<include within="se.jpab.application.*"/>
<include within="se.jpab.aspect.*"/>
</weaver>
<aspects>
<!-- weave in just this aspect -->
<aspect name="se.jpab.aspect.InjectLogg"/>
</aspects>
</aspectj>
Aspect
package se.jpab.aspect;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class InjectLogg {
private static final Log fallbackLogger = LogFactory.getLog(InjectLogg.class);
@Around("execution(public * se.jpab.application..*.*(..))")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
Object invoker = pjp.getThis();
Log logger;
logger = LogFactory.getLog(getClassNameFrom(invoker.getClass()));
// Start injecting logg messages on entering a method.
logger.info("ENTERING: (" + pjp.getSignature().getName() + ")");
try {
logger.info("ARGUMENTS: " + Arrays.toString(pjp.getArgs()) + ")");
} catch (NullPointerException e) {
logger.info("ARGUMENTS: No arguments");
}
try {
// proceed to original method call
Object result = pjp.proceed();
// Injecting exiting messages after method is finished
logger.info("RESULT: " + result);
logger.info("EXITING: (" + pjp.getSignature().getName() + ")");
// Return the result of the method we are logging
return result;
} catch (IllegalArgumentException e) {
// same with ThrowsAdvice
logger.info("Exception. Throws IllegalArgumentException");
throw e;
}
}
private String getClassNameFrom(Class invokerClassName) {
// Function that ....... To be continued JP
// Add check for that string contains $$ and se.goteborg if not then
// return fallback logger class.
String[] classNameParts = invokerClassName.getName().split("$$");
int positionOfPackageName = classNameParts[0].indexOf("se.jpab");
String className = classNameParts[0].substring(positionOfPackageName);
return className;
}
}
Spring configuration (spring.xml)
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:aspectj-autoproxy proxy-target-class="true"/>
<context:load-time-weaver/>
<context:annotation-config />
<context:component-scan base-package="se.jpab"/>
</beans>
Upvotes: 0
Views: 4807
Reputation: 67287
Your first question:
Private methods are not included when the log is weaved around the method. Is there a setting in the xml settings for spring to allow private methods to be weaved or is there another way around this?
If you want to weave private methods, use full AspectJ and therein a privileged aspect, not Spring AOP. The Spring manual says:
If your interception needs include protected/private methods or even constructors, consider the use of Spring-driven native AspectJ weaving instead of Spring's proxy-based AOP framework. This constitutes a different mode of AOP usage with different characteristics, so be sure to make yourself familiar with weaving first before making a decision.
Your second question:
I have to include all packages that are to be weaved in the META-INF/aop.xml for this to be able to work. Is there a setting to be used so that the log information can be weaved for all classes created in the project without having to add the package name to the aop.xml.
You can catch a package an all its subpackages with the ..
syntax, e.g. se.jpab.application..*
or even se.jpab..*
. You can also combine several conditions with boolean operators. See the AspectJ documentation for examples.
Upvotes: 2