I am using the below code to log entry, exit and exceptions using aspects. This way I have to define a bean for every class in my application in my ApplicationContext and it becomes cumbersome to maintain such length of bean definitions and their properties. Can you help me simplify this? I don't think it is appropriate design to define bean everytime I create a class. Help is appreciated, thanks in advance.
<bean id="logEntryBean" class="com.example.logging.LogEntry" />
<bean id="logExitBean" class="com.example.logging.LogReturn" />
<bean id="logExceptionBean" class ="com.example.logging.ExceptionLogger"/>
<bean id="simpleServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="simpleServiceBean" />
<property name="interceptorNames">
<list>
<value>logEntryBean</value>
<value>logExitBean</value>
<value>logExceptionBean</value>
</list>
</property>
</bean>
<bean id="secondServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="secondServiceBean" />
<property name="interceptorNames">
<list>
<value>logEntryBean</value>
<value>logExitBean</value>
<value>logExceptionBean</value>
</list>
</property>
</bean>
==================== LogEntry class:
public class LogEntry implements MethodBeforeAdvice {
private final static Logger logger = Logger.getLogger(LogEntry.class);
public void before(Method method, Object[] args, Object target) throws Throwable {
if(logger.isDebugEnabled())
logger.info("logged entry for method : " + method.getName());
}
========================= LogReturn class:
public class LogReturn implements AfterReturningAdvice {
private final static Logger logger = Logger.getLogger(LogReturn.class);
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
if(logger.isDebugEnabled())
logger.info("Logged exit for method : " + method.getName());
}
============================== ExceptionLogger class
public void afterThrowing(Exception r) throws Throwable {
loadProperties();
// LOG the exceptions
logger.error("Exception : " + r.getMessage());
logger.error(r);
if (logger.isDebugEnabled()) {
// Logging complete stacktrace in better format
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
r.printStackTrace(pw);
logger.debug((sw.toString()));
}
// sendMail();
if (r instanceof ProcessingException) {
throw new OutputException(prop.getProperty("ER004"), r);
} else if (r instanceof SystemException) {
throw new OutputException(Error.DATABASE.toString(), r);
}
}
public void loadProperties() {
// use try with resource
try {
// load a properties file
input = getClass().getClassLoader().getResourceAsStream("ErrorCodes.properties");
prop.load(input);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
======================= Main method:
public class App {
public static void main(String[] args) {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
SimpleService simpleService = (SimpleService) context.getBean("simpleServiceProxy");
SecondService secondService = (SecondService) context.getBean("secondServiceProxy");
// simple call to demo entry and exit logging to the methods of the
// class
simpleService.simpleCall();
secondService.test2();
try {
// processing logic where exception is generated and handled
simpleService.processingOperator();
} catch (Exception e) {
System.out.println(e);
// TODO
// Handle exception
}
// test the service on a different bean
secondService.test3();
context.close();
}
}