spring aop的环绕通知around功能强大,我们这里就不细说,直接上代码,看着注释就能明白

需要的可以点击下载源码

1.如果使用注解的方式则需要先创建个注解类

package com.mb.aop;

import java.lang.annotation.*;

/**
* 常用注解说明:
* 1. RetentionPolicy(保留策略)是一个enum类型,有三个值
* SOURCE -- 这个Annotation类型的信息只会保留在程序源码里,源码如果经过了编译后,Annotation的数据就会消失,并不会保留在编译好的.class文件里
* CLASS -- 这个Annotation类型的信息保留在程序源码中,同时也会保留在编译好的.class文件里面,在执行的时候,并不会把这一些信息加载到虚拟 机(JVM)中去.注意一下,当你没有设定一个Annotation类型的Retention值时,系统默认值是CLASS。
* RUNTIME -- 在源码、编译好的.class文件中保留信息,在执行的时候会把这一些信息加载到JVM中去的。
*
* 2.ElementType @Target中的ElementType用来指定Annotation类型可以用在哪些元素上
* TYPE(类型) -- 在Class,Interface,Enum和Annotation类型上
* FIELD -- 属性上
* METHOD -- 方法上
* PARAMETER -- 参数上
* CONSTRUCTOR -- 构造函数上
* LOCAL_VARIABLE -- 局部变量
* ANNOTATION_TYPE -- Annotation类型上
* PACKAGE -- 包上
*
* 3.Documented -- 让这个Annotation类型的信息能够显示在API说明文档上;没有添加的话,使用javadoc生成的API文件找不到这个类型生成的信息
*/ @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AssertOK { String isLogin() default "false"; }

2.再创建个拦截器,拦截目标方法并在目标方法前后执行操作

package com.mb.aop;
import com.sun.istack.internal.logging.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component; import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.TypeVariable; @Component
@Aspect
public class AssertOKAspectj { private Logger logger = Logger.getLogger(this.getClass()); @Pointcut("@annotation(com.mb.aop.AssertOK)") //表示所有带有AssertOK的注解
public void point(){ } // @Pointcut("execution(* com.mb..*.*(..))") //表示拦截所有com.mb包及子包下的所有的方法
// public void point(){
//
// } @Around(value = "point()")
public Object assertAround(ProceedingJoinPoint pjp){ //判断注解标识如果不为false则,进行登录
Class<?> aClass = pjp.getTarget().getClass(); //先获取被织入增强处理的目标对象,再获取目标类的clazz
String methodName = pjp.getSignature().getName(); //先获取目标方法的签名,再获取目标方法的名
logger.info("methodName: "+methodName); // 输出目标方法名
Class[] parameterTypes = ((MethodSignature) pjp.getSignature()).getParameterTypes(); //获取目标方法参数类型
Object[] args = pjp.getArgs(); //获取目标方法的入参
for (int i = 0; i < args.length; i++) {
logger.info("argsName: "+args[i]); //输出目标方法的参数
}
try {
Method method = aClass.getMethod(methodName, parameterTypes); //获取目标方法
AssertOK annotation = method.getAnnotation(AssertOK.class); //获取方法上的注解
annotation.isLogin(); //获取注解函数值
long starttime = System.currentTimeMillis();
Object proceed = pjp.proceed(); //执行目标方法
long exctime = System.currentTimeMillis() - starttime;
logger.info("执行时间:"+exctime + "毫秒");
logger.info("proceed: "+proceed); //打印目标方法的return结果
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return "aop的返回值";
} }

3.这里为了多场景验证,我创建了2个目标类分别是:Login 、QueryAccount

package com.mb.request;

import com.mb.aop.AssertOK;
import org.springframework.stereotype.Component; @Component
public class Login { @AssertOK(isLogin = "ture")
public String login(String username,String password){
System.out.println(username+" 登录成功 "+", 登录的密码是 "+password);
return "登录成功";
} @AssertOK(isLogin = "false")
public String loginOnline(String name,String pwd){
String login = login(name, pwd);
System.out.println("login 的返回值:"+login);
return "loginOnline 成功";
}
}
package com.mb.request;

import com.mb.aop.AssertOK;
import org.springframework.stereotype.Component; @Component
public class QueryAccount { @AssertOK
public String queryAccount(){ System.out.println("账户查询成功....");
return "success";
}
}

4.配置spring包扫描和自动代码配置,这里默认使用的是jdk动态代理

<?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.xsd"> <!-- 自动扫描web包 ,将带有注解的类 纳入spring容器管理 -->
<context:component-scan base-package="com.mb"></context:component-scan> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

5.最后就是需要我们把pom.xml文件中添加aspectj和spring核心包等

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.mb</groupId>
<artifactId>aspectjdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.20.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

6.以上搞定,下面我们来做测试,验证配置的aop是否生效

package com.mb.request;

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*:**/applicationContext*.xml"})
public class RequestTest { @Autowired
Login login;
@Autowired
QueryAccount queryAccount; @Test
public void loginTest(){
login.loginOnline("米小圈","123456");
}
}

7.测试结果:

二月 27, 2019 12:04:01 上午 [com.mb.aop.AssertOKAspectj]  invoke0
信息: methodName: loginOnline
二月 27, 2019 12:04:01 上午 [com.mb.aop.AssertOKAspectj] invoke0
信息: argsName: 米小圈
二月 27, 2019 12:04:01 上午 [com.mb.aop.AssertOKAspectj] invoke0
信息: argsName: 123456
米小圈 登录成功 , 登录的密码是 123456
login 的返回值:登录成功
二月 27, 2019 12:04:01 上午 [com.mb.aop.AssertOKAspectj] invoke0
信息: 执行时间:15毫秒
二月 27, 2019 12:04:01 上午 [com.mb.aop.AssertOKAspectj] invoke0
信息: proceed: loginOnline 成功

Spring面向切面编程AOP(around)实战的更多相关文章

  1. Spring面向切面编程(AOP)

    1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即 ...

  2. Spring面向切面编程(AOP,Aspect Oriented Programming)

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  3. Spring面向切面编程(AOP)方式二

    使用注解进行实现:减少xml文件的配置. 1 建立切面类 不需要实现任何特定接口,按照需要自己定义通知. package org.guangsoft.utils; import java.util.D ...

  4. Spring学习手札(二)面向切面编程AOP

    AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...

  5. Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)

    一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...

  6. Spring框架学习笔记(2)——面向切面编程AOP

    介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...

  7. Spring之控制反转——IoC、面向切面编程——AOP

      控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...

  8. Spring 面向切面编程(AOP)

    Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...

  9. 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

随机推荐

  1. Jquery Ajax xml版Get请求PHP

    <!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8&qu ...

  2. Lodop在页面获取打印机列表 选择打印机预览

    利用GET_PRINTER_COUNT,获取打印机个数,然后用GET_PRINTER_NAME(intPrinterIndex);循环获取打印机名称,添加到list列表里,可以让用户在页面就选择打印机 ...

  3. Lodop打印条码二维码设置多宽不一定是多宽

    Lodop输出二维码和条码,可用如下语句,其中下面的width和height参数,设置了条码或二维码多宽,会发现可能不是设置的宽度或高度.ADD_PRINT_BARCODE(Top,Left,Widt ...

  4. dfs和bfs(链式前向星实现)

    dfs代码: #include<iostream>#include<Algorithm>#include<cstring>#include<cstdio> ...

  5. window.onload和document.ready

    浏览器解析大致有以下几个步骤: (1)    解析HTML结构 (2)       加载外部脚本和样式 (3)       解析并执行脚本代码 (4)       构造HTML DOM 模型 (5)  ...

  6. 【刷题】UOJ #374 【ZJOI2018】历史

    九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的小说,这本小说的架空世界引起了她的兴趣. 这个世界有 \(n\) 个城市,这 \(n\) 个城市被恰好 \(n-1\) 条双向道路联通, ...

  7. 【刷题】AtCoder Regular Contest 001

    A.センター採点 题意:给一个只包含1.2.3.4的字符串,求出现次数最多和最少的字符 做法:还能怎么做... #include<bits/stdc++.h> #define ui uns ...

  8. 沉迷Link-Cut tree无法自拔之:[BZOJ3669][Noi2014] 魔法森林

    来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记 $ $ 有一个很好的做法是 \(spfa\) ,但是我们不聊 \(spfa\) , 来聊 \(LCT\) \(L ...

  9. 洛谷 P1053 音乐会的等待 解题报告

    P1823 音乐会的等待 题目描述 \(N\)个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人\(A\)和\(B\),如果他们是相邻或他们之 ...

  10. google gson

    发现了google的gson,因为之前对于protocolbuf有一些了解,带着一些好奇心,我开始使用了gson. 经过比较,gson和其他现有java json类库最大的不同时gson需要序列化得实 ...