AOP的介绍

AOP(Aspect-OrientedProgramming,面向方面编程)

AOP的几个概念

1.切面(Aspect):切面就是一个关注点的模块化,如事务管理、日志管理、权限管理等;

2.连接点(Joinpoint):程序执行时的某个特定的点,在Spring中就是一个方法的执行;

3.通知(Advice):通知就是在切面的某个连接点上执行的操作,也就是事务管理、日志管理等;

4.切入点(Pointcut):切入点就是描述某一类选定的连接点,也就是指定某一类要织入通知的方法;

5.目标对象(Target):就是被AOP动态代理的目标对象;

这里使用登录功能做日志管理案例

概要

1)LoginService LogService TestMain

2)用Spring 管理 LoginService 和 LogService 的对象

3)确定哪些连接点是切入点,在配置文件中

4)将LogService封装为通知

5)将通知植入到切入

6)客户端调用目标点

Step1 新建登录业务接口以及实现类



package com.aaron.log; 
/** 

 * @Author Aaron 

 * @Date创建时间:2016-1-13 

 * @Version 1.0  

 * 

 * @Project_Package_Description SpringQuartzDemo || com.aaron.log 

 * @Function_Description登录业务逻辑

* 

 */ 

public interface ILoginService { 
public boolean login(String name, String password); 
}



 



package com.aaron.log; 
/** 

 * @Author Aaron 

 * @Date创建时间:2016-1-13 

 * @Version 1.0  

 * 

 * @Project_Package_Description SpringQuartzDemo || com.aaron.log 

 * @Function_Description登录业务逻辑接口实现类

* 

 */ 

public class LoginServiceImpl implements ILoginService { 
public boolean login(String userName, String password) { 
 System.out.println("用户登录信息:" + userName + "," + password); 
return true; 
 } 
}



Step2 新建日志管理接口以及实现类

 



package com.aaron.log; 
import org.aspectj.lang.JoinPoint; 
/** 

 * @Author Aaron 

 * @Date创建时间:2016-1-13 

 * @Version 1.0  

 * 

 * @Project_Package_Description SpringQuartzDemo || com.aaron.log 

* @Function_Description日志接口

* 

 */ 

public interface ILogService { 

//无参的日志方法
public void beforeLog(); 

//有参的日志方法
public void Log(JoinPoint point); 

//有参有返回值的方法
public void afterLog(JoinPoint point,Object returnObj); 

}



package com.aaron.log; 
import org.aspectj.lang.JoinPoint; 
/** 

 * @Author Aaron 

 * @Date创建时间:2016-1-13 

 * @Version 1.0 

 *  

 * @Project_Package_Description SpringQuartzDemo || com.aaron.log 

 * @Function_Description记录日志接口实现类

*  

 */ 

public class LogServiceImpl implements ILogService { 
    // 无参方法
    public void beforeLog() { 
        System.out.println("*************开始记录日志*******************"); 
    } 

    // 有参无返回值的方法
    public void Log(JoinPoint point) { 
        // 此方法返回的是一个数组,数组中包括request以及ActionCofig等类对象
        Object[] args = point.getArgs(); 
        System.out.print("目标参数列表:"); 
        for (Object obj : args) { 
            System.out.print(obj + ","); 
        } 
        System.out.println(); 
    }  

    // 有参并有返回值的方法

    public void afterLog(JoinPoint point, Object returnObj) { 
        // 此方法返回的是一个数组,数组中包括request以及ActionCofig等类对象
        Object[] args = point.getArgs(); 
        System.out.print("目标参数列表:"); 
        for (Object obj : args) { 
            System.out.print(obj + ","); 
        } 
        System.out.println(); 
        System.out.println("执行结果是:" + returnObj); 
        System.out.println("*************结束记录日志*******************"); 
    } 
}



Step3 在applicationContext.xml文件中配置AOP




Springboot项目使用aop切面保存详细日志到ELK日志平台 spring aop日志切面_spring

Springboot项目使用aop切面保存详细日志到ELK日志平台 spring aop日志切面_System_02

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 

    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

    xmlns:p="http://www.springframework.org/schema/p" 

    xsi:schemaLocation="http://www.springframework.org/schema/beans  

 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 

 http://www.springframework.org/schema/aop  

 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 

    <!-- 启动触发器的配置开始 --> 

    <bean name="startQuertz" lazy-init="false" autowire="no" 

        class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 

        <property name="triggers"> 

            <list> 

                <ref bean="myJobTrigger" /> 

            </list> 

        </property> 

    </bean> 

    <!-- 启动触发器的配置结束 --> 

 

    <!-- 调度的配置开始 --> 

    <!-- quartz-1.8以前的配置 <bean id="myJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  

        <property name="jobDetail"> <ref bean="myJobDetail" /> </property> <property  

        name="cronExpression"> <value>0/1 * * * * ?</value> </property> </bean> --> 

    <!-- quartz-2.x的配置 --> 

    <bean id="myJobTrigger" 

        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> 

        <property name="jobDetail"> 

            <ref bean="myJobDetail" /> 

        </property> 

        <property name="cronExpression"> 

            <value>0 0/1 * * * ?</value> 

        </property> 

    </bean> 

    <!-- 调度的配置结束 --> 

 

    <!-- job的配置开始 --> 

    <bean id="myJobDetail" 

        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 

        <property name="targetObject"> 

            <ref bean="myJob" /> 

        </property> 

        <property name="targetMethod"> 

            <value>work</value> 

        </property> 

    </bean> 

    <!-- job的配置结束 --> 

 

    <!-- 工作的bean --> 

    <bean id="myJob" class="com.tgb.lk.demo.quartz.MyJob" /> 

 

    <bean id="logService" class="com.aaron.log.LogServiceImpl"></bean> 

    <bean id="loginService" class="com.aaron.log.LoginServiceImpl"></bean> 

    <aop:config> 

        <!-- 切入点 --> 

        <aop:pointcut expression="execution(* com.aaron.log.LoginServiceImpl.*(..))" 

            id="myPointcut" /> 

        <!-- 切面:将哪个对象中的哪个方法,织入到哪个切入点 -->

        <aop:aspect id="dd" ref="logService"> 

            <!-- 前置通知 --> 

            <aop:before method="beforeLog" pointcut-ref="myPointcut" /> 

            <aop:after method="Log" pointcut-ref="myPointcut"/> 

            <aop:after-returning method="afterLog" returning="returnObj" pointcut-ref="myPointcut" /> 

        </aop:aspect> 

    </aop:config> 

</beans>


applicationContext.xml


Step4 测试方法



package com.aaron.log;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**

* @Author Aaron

* @Date 创建时间:2016-1-13

* @Version 1.0

*

* @Project_Package_Description SpringQuartzDemo || com.aaron.log

* @Function_Description 测试

*

*/

public class TestMain {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:config/spring/applicationContext.xml");
        ILoginService loginService = (ILoginService) ctx.getBean("loginService");
        loginService.login("aaron", "123456");
    }
}



Step5 运行,看后台

Springboot项目使用aop切面保存详细日志到ELK日志平台 spring aop日志切面_System_03