基於MXL配置的形式在你的spring項目中實現aop日誌輸出!

1.目錄結構長這樣

 2.application.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--向ioc容器中注入bean-->

    <bean id="logAspect" class="com.zlb.spring.aop.LogAspect"></bean>
    <bean id="mathCalculator" class="com.zlb.spring.aop.MathCalculator"></bean>


   <!-- <context:component-scan base-package="com.zlb.spring.aop"></context:component-scan>-->

    <!--切面配置-->
    <aop:config>
        <!-- 配置切面表達式 -->
        <aop:pointcut expression="execution(public * com.zlb.spring.aop.*.*(..))" id="pointcut"/>

        <!-- 配置切面及通知 -->
        <aop:aspect ref="logAspect" order="1">
            <aop:before method="doBefore" pointcut-ref="pointcut"/>
            <aop:after method="doAfter" pointcut-ref="pointcut"/>
            <aop:after-returning method="doAfterReturning" pointcut-ref="pointcut" returning="result"/>
            <aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut" throwing="exception"/>
           <!-- <aop:around method="aroundMethod" pointcut-ref="pointcut"/>-->
        </aop:aspect>
       <!-- <aop:aspect ref="validateAspect" order="2">
            <aop:before method="beforeMethod" pointcut-ref="pointcut"/>
        </aop:aspect>-->
    </aop:config>
</beans>

3.java類這樣寫

(1)LogAspect.java

package com.zlb.spring.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/*@Component
@Aspect
@Order(1)*/
public class LogAspect {
    private org.apache.log4j.Logger logger = Logger.getLogger(this.getClass());
   /* @Pointcut("execution(public * com.zlb.spring.aop.*.*(..))")
    public  void  pointCut(){}*/

   // @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint){
        logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" start");
        logger.info("args : " + Arrays.toString(joinPoint.getArgs()));
    }

    //@After("pointCut()")
    public void doAfter(JoinPoint joinPoint){
        logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" end");
    }

   // @AfterReturning(returning ="result",value = "pointCut()")
    public void doAfterReturning(Object result){
       logger.info("returned"+result);
    }

    //@AfterThrowing(value = "pointCut()",throwing = "exception")
    public void doAfterThrowing(Exception exception){
        logger.info("method exception"+exception.getMessage());
    }
}

(2)MathCalculator.java

package com.zlb.spring.aop;

import org.springframework.stereotype.Component;

/*@Component*/
public class MathCalculator {
    public int getDiv(int x,int y){
        return x/y;
    }
}

(3)測試類這樣寫

package com.zlb.spring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAop {
    public static void main(String[] args) {
        /*ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LogConfig.class);*/
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        System.out.println("ioc 容器舒適化完成!");
        //打印logger日誌
        MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
        mathCalculator.getDiv(6,1);
    }
}

注:沒寫的出來的log4j配置文件在上一篇基於配置類實現aop的博客中已經寫過,這裏我們是基於xml配置文件的方式來實現所以便沒有LogConfig.java

思考:我們可不可以使用<context:component-scan base-package="com.zlb.spring.aop"></context:component-scan>加註解的方式實現aop呢?

驗證:

(1).applicationContex.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.zlb.spring.aop"></context:component-scan>

</beans>

(2).LogAspect.java這樣寫

package com.zlb.spring.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect
@Order(1)
public class LogAspect {
    private org.apache.log4j.Logger logger = Logger.getLogger(this.getClass());
    @Pointcut("execution(public * com.zlb.spring.aop.*.*(..))")
    public  void  pointCut(){}

    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint){
        logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" start");
        logger.info("args : " + Arrays.toString(joinPoint.getArgs()));
    }

    @After("pointCut()")
    public void doAfter(JoinPoint joinPoint){
        logger.info("class_method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()+" end");
    }

    @AfterReturning(returning ="result",value = "pointCut()")
    public void doAfterReturning(Object result){
       logger.info("returned"+result);
    }

    @AfterThrowing(value = "pointCut()",throwing = "exception")
    public void doAfterThrowing(Exception exception){
        logger.info("method exception"+exception.getMessage());
    }
}

(2)MathCalculator.java這樣寫

@Component
public class MathCalculator {
    public int getDiv(int x,int y){
        return x/y;
    }
}

(3)測試類這樣寫

package com.zlb.spring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAop {
    public static void main(String[] args) {
        /*ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LogConfig.class);*/
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        System.out.println("ioc 容器舒適化完成!");
        //打印logger日誌
        MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
        mathCalculator.getDiv(6,1);
    }
}

(4).兩種方式的運行結果都長這樣

ioc 容器舒適化完成!
[INFO][2019-06-28 14:58:19,746][main][com.zlb.spring.aop.LogAspect][class_method : com.zlb.spring.aop.MathCalculator.getDiv start]
[INFO][2019-06-28 14:58:19,747][main][com.zlb.spring.aop.LogAspect][args : [6, 1]]
[INFO][2019-06-28 14:58:19,765][main][com.zlb.spring.aop.LogAspect][class_method : com.zlb.spring.aop.MathCalculator.getDiv end]
[INFO][2019-06-28 14:58:19,765][main][com.zlb.spring.aop.LogAspect][returned6]

Process finished with exit code 0

所以:spring實現aop一共有三種方式,但是純xml的方式比較麻煩,xml與註解的方式比較常見,但是不夠靈活,所以目前企業比較流行的是基於註解與配置類的方式!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章