spring 框架aop(面向切面编程) xmi配置,注解配置,日志跟踪

xml配置

spring结构

spring 框架aop(面向切面编程) xmi配置,注解配置,日志跟踪_第1张图片

引入依赖(pom.xml)


      org.springframework
      spring-aop
      5.2.8.RELEASE
    
    
      org.aspectj
      aspectjrt
      1.9.5
    
    
      org.aspectj
      aspectjweaver
      1.9.5
    

编写通知类(LogAdvise)

package com.tmg.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class LogAdvise {
    
    public void beforeLog(JoinPoint joinPoint){
        System.out.println("这是前置通知");
        System.out.println("方法的名称:"+joinPoint.getSignature().getName());
        Object[] args = joinPoint.getArgs();
        for (Object arg:args){
            System.out.println("arg==>"+arg);
        }
    }

    public void afterLog(){
        System.out.println("这是后置通知");
    }

    public void afterReturningLog(){
        System.out.println("这是最终通知");
    }

    public void afterThrowingLog(JoinPoint joinPoint,Throwable throwable1){
        System.out.println("这是异常通知");
        System.out.println("异常信息:"+throwable1.getMessage());
        StackTraceElement[] stackTrace = throwable1.getStackTrace();
        for (StackTraceElement stackTraceElement :stackTrace){
            System.out.println("详细异常堆栈:类"+stackTraceElement.getClassName());
            System.out.println("详细异常堆栈:文件"+stackTraceElement.getFileName());
            System.out.println("详细异常堆栈:方法"+stackTraceElement.getMethodName());
            System.out.println("详细异常堆栈:行"+stackTraceElement.getLineNumber());
        }
    }

    public void aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("这是环绕前置通知");
        Object proceed = joinPoint.proceed();
        System.out.println("执行方法了,返回值:"+proceed);
        System.out.println("这是环绕后置通知");
    }
}

创建Goods类,后续创建对象用

package com.tmg.domain;
public class Goods {
    private int id;
    private int manageId;
    private String name;
    private double price;
    private int inId;
    private String time;

    public Goods(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getManageId() {
        return manageId;
    }

    public void setManageId(int manageId) {
        this.manageId = manageId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getInId() {
        return inId;
    }

    public void setInId(int inId) {
        this.inId = inId;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", manageId=" + manageId +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", inId=" + inId +
                ", time='" + time + '\'' +
                '}';
    }
}

写几个用于测试的方法 加注解(@Component) 让spring容器创建对象(AspectServicceImpl)

package com.tmg.service;

import com.tmg.domain.Goods;
import org.springframework.stereotype.Component;

@Component
public class AspectServicceImpl {
    public void add(Goods goods){
        System.out.println("add1");
    }
    public void delete(){
        System.out.println("delete1");
        throw new RuntimeException("出错辣,我干的!");
    }
    public void update(){
        System.out.println("update1");
    }
    public String query(){
        System.out.println("query1");
        return "zl";
    }
}

xml配置(spring.xml) *-所以 …-任意




    

    

    

        

        

            
            
            
            
            
        
    

测试类(LogAdviseText1)

会报错,原因是delete方法里面我抛出错误

package text;

import com.tmg.domain.Goods;
import com.tmg.service.AspectServicceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class LogAdviseText1 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
        AspectServicceImpl bean = app.getBean(AspectServicceImpl.class);
        bean.add(new Goods("tmg"));
        System.out.println("--------------------------------------------------");
        bean.delete();
        bean.query();
    }
}

注解+日志跟踪

spring结构

spring 框架aop(面向切面编程) xmi配置,注解配置,日志跟踪_第2张图片

引入依赖(pom.xml)


    
      junit
      junit
      4.12
      test
    
    
      org.springframework
      spring-test
      5.2.8.RELEASE
    

      org.springframework
      spring-aop
      5.2.8.RELEASE
    
    
      org.aspectj
      aspectjrt
      1.9.5
    
    
      org.aspectj
      aspectjweaver
      1.9.5
    
    
        
      log4j
      log4j
      1.2.12
    

编写通知类(LogAdvise)

package com.tmg.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
 * 日志切面
 */
//@Aspect
//表示创建对象
//@Component
public class LogAdvise {
    //配置切入点
    @Pointcut("execution(* com.tmg.service.*ServicceImpl.*(..))")
    public void pointcut(){}

    @Before("pointcut()")
    public void beforeLog(JoinPoint joinPoint){
        System.out.println("这是前置通知");
        System.out.println("方法的名称:"+joinPoint.getSignature().getName());
        Object[] args = joinPoint.getArgs();
        for (Object arg:args){
            System.out.println("arg==>"+arg);
        }
    }
    @After("pointcut()")
    public void afterLog(){
        System.out.println("这是后置通知");
    }
    @AfterReturning("pointcut()")
    public void afterReturningLog(){
        System.out.println("这是最终通知");
    }
    @AfterThrowing(value = "pointcut()",throwing = "throwable1")
    public void afterThrowingLog(JoinPoint joinPoint,Throwable throwable1){
        System.out.println("这是异常通知");
        System.out.println("异常信息:"+throwable1.getMessage());
        StackTraceElement[] stackTrace = throwable1.getStackTrace();
        for (StackTraceElement stackTraceElement :stackTrace){
            System.out.println("详细异常堆栈:类"+stackTraceElement.getClassName());
            System.out.println("详细异常堆栈:文件"+stackTraceElement.getFileName());
            System.out.println("详细异常堆栈:方法"+stackTraceElement.getMethodName());
            System.out.println("详细异常堆栈:行"+stackTraceElement.getLineNumber());
        }
    }
    @Around("pointcut()")
    public void aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("这是环绕前置通知");
        Object proceed = joinPoint.proceed();
        System.out.println("执行方法了,返回值:"+proceed);
        System.out.println("这是环绕后置通知");
    }
}

配置类(AspectConfig)相当于xml配置文件

package com.tmg.aspect;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
//启动AspectJ的注解配置
@EnableAspectJAutoProxy
//用于扫描某一个包下带@Component的类
@ComponentScan(basePackages = "com.tmg")
//配置类,标记在类上,该类作为配置类代替XML
@Configuration
public class AspectConfig {
}

创建Goods类,后续创建对象用

package com.tmg.domain;
public class Goods {
    private int id;
    private int manageId;
    private String name;
    private double price;
    private int inId;
    private String time;

    public Goods(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getManageId() {
        return manageId;
    }

    public void setManageId(int manageId) {
        this.manageId = manageId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getInId() {
        return inId;
    }

    public void setInId(int inId) {
        this.inId = inId;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", manageId=" + manageId +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", inId=" + inId +
                ", time='" + time + '\'' +
                '}';
    }
}

写用于测试的方法 加注解(@Component) 让spring容器创建对象(AspectServicceImpl)

package com.tmg.service;

import com.tmg.domain.Goods;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Service
public class AspectServicceImpl {
    public void add(Goods goods){
        System.out.println("add1");
    }
    public void delete(){
        System.out.println("delete1");
        throw new RuntimeException("出错辣,我干的!");
    }
    public void update(){
        System.out.println("update1");
    }
    public String query(){
        System.out.println("query1");
        return "zl";
    }
}

日志跟踪

编写properties文件
log4j.rootLogger =DEBUG,systemOut,logFile

#输出到控制台
log4j.appender.systemOut = org.apache.log4j.ConsoleAppender 
log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout 
log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}] %m%n
log4j.appender.systemOut.Threshold = DEBUG 
log4j.appender.systemOut.ImmediateFlush = TRUE 
log4j.appender.systemOut.Target = System.out 

#输出到文件
log4j.appender.logFile = org.apache.log4j.FileAppender 
log4j.appender.logFile.layout = org.apache.log4j.PatternLayout 
log4j.appender.logFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}] %m%n
log4j.appender.logFile.Threshold = DEBUG 
log4j.appender.logFile.ImmediateFlush = TRUE 
log4j.appender.logFile.Append = TRUE 
log4j.appender.logFile.File = D:\\javaLog\\systemLogs.log 
log4j.appender.logFile.Encoding =UTF-8 
编写日志切面(Log4j)
package com.tmg.aspect;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class Log4j {
    //创建日志对象
    private Logger logger = Logger.getLogger(Log4j.class);
    //给所有的service类的所有方法加日志跟踪
    @Around("execution(* com.tmg.service.*ServicceImpl.*(..))")
    public Object printLog(ProceedingJoinPoint joinPoint){

        if(logger.isDebugEnabled()){
            //打印方法名称
            logger.debug("当前执行的方法:" + joinPoint.getSignature().getName());
        }
        Object[] args = joinPoint.getArgs();
        //打印参数
        for(Object arg : args){
            if(logger.isDebugEnabled()){
                logger.debug("参数:" + arg);
            }
        }
        //记录方法执行前时间
        long start = System.currentTimeMillis();
        Object result=null;
        try {
            //执行原有方法
            result = joinPoint.proceed(args);
            if(logger.isDebugEnabled()){
                logger.debug("执行返回值:" + result);
            }
        } catch (Throwable throwable) {
            logger.error("出现异常",throwable);
        }

        long end = System.currentTimeMillis();
        //打印执行时间
        if(logger.isDebugEnabled()){
            logger.debug("方法执行结束,执行时间是:" + (end - start));
        }
        return result;
    }
}

测试类

package com.tmg.text;

import com.tmg.aspect.AspectConfig;
import com.tmg.domain.Goods;
import com.tmg.service.AspectServicceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(locations = "classpath:spring.xml")
@ContextConfiguration(classes = AspectConfig.class)
public class text1 {
    @Autowired
    private AspectServicceImpl aspectServicce;

    @Test
    public void text1(){
        aspectServicce.add(new Goods("tmg1"));
        System.out.println("********************************************************");
        aspectServicce.query();
    }
}

你可能感兴趣的:(spring,java,后端)