使用方面记录Java中方法的进入,退出和异常 [英] Logging entry, exit and exceptions for methods in java using aspects

查看:76
本文介绍了使用方面记录Java中方法的进入,退出和异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码记录使用方面的进入,退出和异常.这样,我必须在ApplicationContext中为应用程序中的每个类定义一个bean,而要保持如此长的bean定义及其属性变得很麻烦.您能帮我简化一下吗?我认为在每次创建类时都定义bean是不合适的设计.感谢您的帮助,在此先感谢.

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类:

==================== 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类:

========================= 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类

============================== 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();
}

}

推荐答案

您可以使用Spring的组件扫描来自动装配bean.

you can use Spring's component scan to autowire your beans.

只需添加

<context:component-scan base-package="<PACKAGE>" />

到您的applicationContext.xml.您必须用要扫描bean的软件包替换".

to your applicationContext.xml. You have to replace "" with the package you want to scan for beans.

此外,您还必须使用

@Component

向Spring说嘿,这是一个豆子".要将依赖项注入其他bean,只需将字段标记为

to say "hey, this is a bean" to Spring. To inject dependencies into other beans, simply tag the field with

@Autowired

它们将被注入.

我希望这会有所帮助:).

I hope this will help :).

〜法比安

如何使用spring-aop和AspectJ.

How to use spring-aop and AspectJ.

您必须添加

<aop:aspectj-autoproxy />

到您的applicationContext.xml.然后,您必须定义一个包含方面的类.此类是基本的Spring bean,带有

to your applicationContext.xml. Then, you have to define a class that will contain your aspects. This class is a basic Spring bean, annotated with

@Component

然后,您必须定义要通过切入点执行日志记录的连接点.

Then you have to define the join-points where you want to execute your logging via pointcuts.

示例:

@Around("execution(* <BASE_PACKAGE>..*.* (..))")
public Object logAll(PreecedingJoinPoint joinPoint) throws Throwable {
    Object result = null;
    Throwable throwable = null;

    final StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    try {
        result = joinPoint.proceed();
    } catch (Throwable t) {
        throwable = t;
    }
    stopWatch.stop();

    if (throwable == null) {
        LOGGER.debug("Executed " + joinPoint.getSignature() + " in " + stopWatch.getTime() + "ms!");
    } else {
        LOGGER.debug("Executed " + joinPoint.getSignature() + " in " + stopWatch.getTime() + "ms! Threw an exception: " + throwable);
        throw throwable;
    }
    return result;
}

您可以通过joinPoint.proceed()继续执行.返回结果很重要!否则,每个方法都将返回null!另外,您必须抛出抛出的异常,否则它将被抑制.

You continue the execution via joinPoint.proceed(). It is important that you return the result! Otherwise, every method will return null! Also, you must throw the thrown exception, otherwise it will be suppressed.

这篇关于使用方面记录Java中方法的进入,退出和异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆