zoukankan      html  css  js  c++  java
  • 【Spring】简单的Spring AOP注解示例

    如何配置,以及相关知识

    引入相关包:

    <properties>
    	<spring.version>3.0.5.RELEASE</spring.version>
    	<aspectj.version>1.6.11</aspectj.version>
    </properties>
    
    <dependencies>
    
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-core</artifactId>
    		<version>${spring.version}</version>
    	</dependency>
    
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-context</artifactId>
    		<version>${spring.version}</version>
    	</dependency>
    
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-aop</artifactId>
    		<version>${spring.version}</version>
    	</dependency>
    
    	<dependency>
    		<groupId>org.aspectj</groupId>
    		<artifactId>aspectjrt</artifactId>
    		<version>${aspectj.version}</version>
    	</dependency>
    
    	<dependency>
    		<groupId>org.aspectj</groupId>
    		<artifactId>aspectjweaver</artifactId>
    		<version>${aspectj.version}</version>
    	</dependency>
    
    	<dependency>
    		<groupId>cglib</groupId>
    		<artifactId>cglib</artifactId>
    		<version>3.1</version>
    	</dependency>
    
    </dependencies>
    

    在Spring配置文件开启注解、AspectJ支持、扫描基础包:

    <?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:context="http://www.springframework.org/schema/context" 
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/context 
               http://www.springframework.org/schema/context/spring-context-3.0.xsd
               http://www.springframework.org/schema/aop 
               http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
               
        <!-- 开启注解 -->
      	<context:annotation-config/>
      	<!-- AspectJ支持 -->
      	<aop:aspectj-autoproxy />
        <!-- 扫描基础包 -->
        <context:component-scan base-package="com.nicchagil.springaop" />
        
    </beans>
    

    写两个测试的Service:

    package com.nicchagil.springaop;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
    	
    	public void query(Integer id) {
    		System.out.println("UserService.query()...");
    	}
    
    }
    
    
    package com.nicchagil.springaop;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class FunctionService {
    	
    	public void query() {
    		System.out.println("FunctionService.query()...");
    	}
    
    }
    
    

    切面的信息:

    package com.nicchagil.springaop;
    
    import java.util.Arrays;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class MyAOP {
    	
    	@Pointcut("execution(* com.nicchagil.springaop.*Service.query(..))")
    	public void myPointcut() {
    	}
    	
    	@Before("myPointcut()")
    	public void myBefore(JoinPoint joinPoint) {
    		Object[] args = joinPoint.getArgs(); // 入参
    		System.out.println("Before. Args : " + Arrays.toString(args));
    	}
    	
    	@AfterReturning("myPointcut()")
    	public void myAfterReturning() {
    		System.out.println("AfterReturning.");
    	}
    	
    	@AfterThrowing("myPointcut()")
    	public void myAfterThrowing() {
    		System.out.println("AfterThrowing.");
    	}
    
    }
    
    

    下图可帮助理解通知(Advice)、切点(PointCut)、切面(Aspect)、织入(Weaving)各大术语:

    入口类:

    package com.nicchagil.springaop;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class HowToUse {
    	
    	public static void main(String[] args) {
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("spring.xml");
            
            UserService us = context.getBean("userService", UserService.class);
            us.query(100);
            
            FunctionService fs = context.getBean("functionService", FunctionService.class);
            fs.query();
        }
    
    }
    
    

    日志:

    Before. Args : [100]
    UserService.query()...
    AfterReturning.
    Before. Args : []
    FunctionService.query()...
    AfterReturning.
    

    常用的AOP

    添加AOP:

    package com.nicchagil.exercise.springbootexercise.aop;
    
    import java.lang.reflect.Method;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Configuration;
    
    @Aspect
    @Configuration
    public class AopExample {
    
    	private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    	@Pointcut("execution(* com.nicchagil.exercise.springbootexercise.service..*.*(..))")
    	public void serviceAllMethodPointcut() {
    	}
    	
    	@Around("serviceAllMethodPointcut()")
    	public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    		/* 获取常用的对象 */
    		Object targetObject = proceedingJoinPoint.getThis(); // 目标对象
    		Object[] args = proceedingJoinPoint.getArgs(); // 入参
    		Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod(); // 方法对象
    
    		this.logger.info("@Around targetObject : {}, args : {}, method : {}", targetObject, args, method);
    		
    		Object result = proceedingJoinPoint.proceed(); // 执行被拦截的代码
    		this.logger.info("@Around result : {}", result);
    		
    		return result; // 记得返回
    	}
    
    	@Before("serviceAllMethodPointcut()")
    	public void myBefore(JoinPoint joinPoint) {
    		/* 获取常用的对象 */
    		Object targetObject = joinPoint.getThis(); // 目标对象
    		Object[] args = joinPoint.getArgs(); // 入参
    		Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); // 方法对象
    
    		this.logger.info("@Before targetObject : {}, args : {}, method : {}", targetObject, args, method);
    	}
    
    	@AfterReturning(value = "serviceAllMethodPointcut()", returning = "returningObject")
    	public void myAfterReturning(JoinPoint joinPoint, Object returningObject) {
    		/* 获取常用的对象 */
    		Object targetObject = joinPoint.getThis(); // 目标对象
    		Object[] args = joinPoint.getArgs(); // 入参
    		Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); // 方法对象
    
    		this.logger.info("@AfterReturning targetObject : {}, args : {}, method : {}, returningObject : {}",
    				targetObject, args, method, returningObject);
    	}
    	
    	@AfterThrowing(value = "serviceAllMethodPointcut()", throwing="throwable")
    	public void myAfterThrowing(JoinPoint joinPoint, Throwable throwable) {
    		/* 获取常用的对象 */
    		Object targetObject = joinPoint.getThis(); // 目标对象
    		Object[] args = joinPoint.getArgs(); // 入参
    		Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); // 方法对象
    
    		this.logger.info("@AfterThrowing targetObject : {}, args : {}, method : {}, throwable : {}",
    				targetObject, args, method, throwable);
    	}
    
    }
    

    日志打印(异常的情况就没演示了):

    2018-01-06 10:34:13.207  INFO 7176 --- [           main] Example$$EnhancerBySpringCGLIB$$ed744e46 : @Around targetObject : com.nicchagil.exercise.springbootexercise.service.UserService@67b100fe, args : [1], method : public com.nicchagil.exercise.springbootexercise.mapper.entity.User com.nicchagil.exercise.springbootexercise.service.UserService.selectByPrimaryKey(java.lang.Long)
    2018-01-06 10:34:13.223  INFO 7176 --- [           main] Example$$EnhancerBySpringCGLIB$$ed744e46 : @Before targetObject : com.nicchagil.exercise.springbootexercise.service.UserService@67b100fe, args : [1], method : public com.nicchagil.exercise.springbootexercise.mapper.entity.User com.nicchagil.exercise.springbootexercise.service.UserService.selectByPrimaryKey(java.lang.Long)
    2018-01-06 10:34:13.582  INFO 7176 --- [           main] Example$$EnhancerBySpringCGLIB$$ed744e46 : @Around result : User [id=1, name=Nick Huang, age=20, createTime=Sat Nov 25 00:00:00 CST 2017]
    2018-01-06 10:34:13.582  INFO 7176 --- [           main] Example$$EnhancerBySpringCGLIB$$ed744e46 : @AfterReturning targetObject : com.nicchagil.exercise.springbootexercise.service.UserService@67b100fe, args : [1], method : public com.nicchagil.exercise.springbootexercise.mapper.entity.User com.nicchagil.exercise.springbootexercise.service.UserService.selectByPrimaryKey(java.lang.Long), returningObject : User [id=1, name=Nick Huang, age=20, createTime=Sat Nov 25 00:00:00 CST 2017]
    
  • 相关阅读:
    疑似CPU或者内存故障导致进程崩溃
    free如何知道释放内存长度:vs与glibc分配内存时编译器内部处理
    stun简介
    H264(NAL简介与I帧判断)
    H264码率设置
    简单的makefile模板
    ffmpeg显示视频
    一些yuv视频下载地址
    转载:P2P技术原理及应用(2)
    转载:P2P技术原理及应用(1)
  • 原文地址:https://www.cnblogs.com/nick-huang/p/6147837.html
Copyright © 2011-2022 走看看