Spring AOP技术(基于AspectJ)的Annotation开发
来源:互联网 发布:java中main是什么意思 编辑:程序博客网 时间:2024/05/16 11:02
Spring AOP技术(基于AspectJ)的Annotation开发
@(Spring)[aop, spring, xml, Spring, annotation, aspectJ]
- Spring AOP技术基于AspectJ的Annotation开发
- Spring AOP的Annotation的开发
- Spring的基于AspectJ的AOP的Annotation开发
- 第一步引入jar包
- 第二步创建配置文件
- 第三步创建需增强包和类
- 第四步将类交给Spring管理
- 第五步编写测试
- 第六步编写切面类和通知
- 第七步 配置切面类
- 第八步开启AOP的自动代理
- 第九步通过注解实现AOP
- 第九步执行测试
- 通知类型
- 前置通知
- 配置切面和通知
- 单元测试
- 后置通知
- 配置切面和通知
- 单元测试
- 环绕通知
- 配置切面和通知
- 单元测试
- 异常抛出通知
- 配置切面和通知
- 单元测试
- 最终通知
- 配置切面和通知
- 单元测试
- 前置通知
- 切入点的注解
- Spring AOP小项目
- Spring的基于AspectJ的AOP的Annotation开发
- Spring AOP的Annotation的开发
Spring AOP的Annotation的开发
Spring的基于AspectJ的AOP的Annotation开发
第一步引入jar包
第二步创建配置文件
- 引入AOP的约束
<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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>
第三步创建需增强包和类
- 创建接口
package com.pc.aop.dao;/** * 客户持久层接口 * * @author Switch * @data 2016年11月23日 * @version V1.0 */public interface CustomerDao { /** * 保存用户 */ public void save();}
- 创建实现类
package com.pc.aop.dao.impl;import com.pc.aop.dao.CustomerDao;/** * 用户持久层实现类 * * @author Switch * @data 2016年11月23日 * @version V1.0 */public class CustomerDaoImpl implements CustomerDao { @Override public void save() { System.out.println("保存用户了。。。"); }}
第四步将类交给Spring管理
<bean id="customerDao" class="com.pc.aop.dao.impl.CustomerDaoImpl" />
第五步编写测试
package com.pc.test;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.pc.aop.dao.CustomerDao;/** * 面向切面编程测试类 * * @author Switch * @data 2016年11月23日 * @version V1.0 */// 配置Spring单元测试环境@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringAOPTest { // 注入依赖 @Resource(name = "customerDao") private CustomerDao customerDao; // 测试Spring单元测试集成 @Test public void testSpring() { customerDao.save(); }}
输出
保存用户了。。。
PS:这时候没用使用AOP进行任何增强
第六步编写切面类和通知
package com.pc.aop.advice;import org.aspectj.lang.ProceedingJoinPoint;/** * 切面类 * * @author Switch * @data 2016年11月23日 * @version V1.0 */public class MyAspect { // 通知:校验权限 public void check() { System.out.println("校验权限。。。。。。"); }}
第七步 配置切面类
<!-- 配置切面类 --><bean id="myAspect" class="com.pc.aop.advice.MyAspect"/>
第八步开启AOP的自动代理
<!-- 开启AOP注解自动代理 --><aop:aspectj-autoproxy/>
第九步通过注解实现AOP
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面@Aspectpublic class MyAspect { // 前置通知 @Before("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.save(..))") // 通知:校验权限 public void check() { System.out.println("校验权限。。。。。。"); }}
第九步执行测试
package com.pc.test;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.pc.aop.dao.CustomerDao;/** * 面向切面编程测试类 * * @author Switch * @data 2016年11月23日 * @version V1.0 */// 配置Spring单元测试环境@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringAOPTest { // 注入依赖 @Resource(name = "customerDao") private CustomerDao customerDao; // 测试Spring单元测试集成 @Test public void testSpring() { customerDao.save(); }}
输出
校验权限。。。。。。保存用户了。。。
通知类型
PS:因为在XML中已经给出了各个通知的完整测试代码,所以这里只给出通知代码和测试代码及其结果,如果想查看其他代码,请查找《Spring AOP技术(基于AspectJ)的XML开发》
前置通知
前置通知:在目标方法执行之前完成的增强。获得切入点信息。
注解:@Before
PS:接入点信息,其他类型的增强也可以通过这种方法使用。
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面@Aspectpublic class MyAspect { // 前置通知 @Before("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.save(..))") // 通知:校验权限 public void check(JoinPoint joinPoint) { System.out.println("校验权限。。。。。。"); // 输出接入点信息 System.out.println(joinPoint.toString()); }}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringAOPTest { // 注入依赖 @Resource(name = "customerDao") private CustomerDao customerDao; // 测试前置通知 @Test public void testBefore() { customerDao.save(); }}
输出
校验权限。。。。。。execution(void com.pc.aop.dao.CustomerDao.save())保存用户了。。。
后置通知
后置通知:在目标方法执行之后完成的增强。获得方法的返回值。
注解:@AfterReturning
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面@Aspectpublic class MyAspect { // 后置通知 @AfterReturning(value = "execution(* com.pc.aop.dao.impl.CustomerDaoImpl.delete(..))", returning = "retVal") // 通知:打印日志 public void printLog(String retVal) { System.out.println("打印日志。。。。。"); System.out.println("返回值为:" + retVal); }}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringAOPTest { // 注入依赖 @Resource(name = "customerDao") private CustomerDao customerDao; // 测试后置通知 @Test public void testAfterRunning() { String delete = customerDao.delete(); System.out.println(delete); }}
输出
删除用户了。。。打印日志。。。。。返回值为:deletedelete
环绕通知
环绕通知:在目标方法执行前和执行后完成的增强。阻止目标方法的执行,获得方法参数。
注解:@Around
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面@Aspectpublic class MyAspect { // 环绕通知 @Around("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.update(..))") // 通知:计算方法耗时 public void calTime(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("方法执行前。。。。。。"); // 打印参数 System.out.println("参数为:" + joinPoint.getArgs()[0]); // 执行目标方法 joinPoint.proceed(); System.out.println("方法执行后。。。。。。"); }}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringAOPTest { // 注入依赖 @Resource(name = "customerDao") private CustomerDao customerDao; // 测试环绕通知 @Test public void testAround() { customerDao.update(6166); }}
输出
方法执行前。。。。。。参数为:6166更新用户了。。。方法执行后。。。。。。
异常抛出通知
异常抛出通知:在目标方法执行出现异常的时候完成的增强。获得异常的信息。
注解:@AfterThrowing
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面@Aspectpublic class MyAspect { // 异常通知 @AfterThrowing(value = "execution(* com.pc.aop.dao.impl.CustomerDaoImpl.find(..))", throwing = "ex") // 通知:异常处理 public void throwHandler(Throwable ex) { System.out.println("异常处理。。。。。。" + ex.getMessage()); }}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringAOPTest { // 注入依赖 @Resource(name = "customerDao") private CustomerDao customerDao; // 测试异常通知 @Test public void testAfterThrowing() { customerDao.find(); }}
输出
查询用户了。。。异常处理。。。。。。/ by zero
最终通知
最终通知:无论目标方法是否出现异常总是执行的增强。
注解:@After
PS:该案例和异常测试案例对同一个target进行增强。
配置切面和通知
// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面@Aspectpublic class MyAspect { // 最终通知 @After("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.find(..))") // 通知:关闭资源 public void close() { System.out.println("关闭资源。。。。。。"); }}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringAOPTest { // 注入依赖 @Resource(name = "customerDao") private CustomerDao customerDao; // 测试最终通知 @Test public void testFinally() { customerDao.find(); }}
输出
查询用户了。。。关闭资源。。。。。。异常处理。。。。。。/ by zero
切入点的注解
在上面的案例中,都是在通知上面直接定义切入点。这样有一个比较麻烦的问题,也就是如果我们需要修改多个通知相同的切入点,那么需要改大量的切入点代码。
上面的问题,可以通过使用切入点注解@Pointcut
解决。
案例:
package com.pc.aop.advice;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;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;/** * 切面类 * * @author Switch * @data 2016年11月23日 * @version V1.0 */// 配置了自动AOP代理的,需要在类上配置该注解,不然无法被识别为切面@Aspectpublic class MyAspect { // 异常通知 @AfterThrowing(value = "com.pc.aop.advice.MyAspect.pointcut1()", throwing = "ex") // 通知:异常处理 public void throwHandler(Throwable ex) { System.out.println("异常处理。。。。。。" + ex.getMessage()); } // 最终通知 @After("com.pc.aop.advice.MyAspect.pointcut1()") // 通知:关闭资源 public void close() { System.out.println("关闭资源。。。。。。"); } // 配置切入点 @Pointcut("execution(* com.pc.aop.dao.impl.CustomerDaoImpl.find(..))") public void pointcut1() {}}
PS:切入点的注解需要定义在方法上,切入点方法一般是无意义的。如果需要使用切入点方法,只需要在通知声明中写入包名.类型.方法名()
,如果通知和切入点在一个类中,那么也可以直接写入方法名()
Spring AOP小项目
GitHub:Spring AOP小项目
GitHub:MyStore-netease
- Spring AOP技术(基于AspectJ)的Annotation开发
- Spring AOP技术(基于AspectJ)的XML开发
- Spring基于annotation的AOP(AspectJ)
- Spring的基于AspectJ的AOP开发
- Spring AOP基于@AspectJ开发
- Spring AOP + AspectJ annotation
- Spring AspectJ Aop Annotation
- Spring AOP(二)(Spring中基于AOP的@AspectJ)
- Spring-AOP:基于AspectJ注解的AOP
- Spring Aop开发基于AspectJ注解方式的案例
- Spring(十一)AspectJ框架开发AOP(基于xml)
- Spring(十二)AspectJ框架开发AOP(基于注解)
- Spring AOP + AspectJ Annotation Example
- Spring AOP + AspectJ Annotation Example
- Spring AOP + AspectJ Annotation Example
- spring aop + aspectj annotation example
- Spring AOP + AspectJ annotation example
- Spring AOP + AspectJ annotation example
- String类型的比较(为什么比较字符串是否相等时不用=号用equals()的)
- linux系统修改系统时间重启后导致文件系统错误原因以及修复方法
- iOS 10 开发适配系列 之 权限Crash问题
- Android获取可用内存(系统,sd卡,u盘)
- ubuntu下安装php5.6开发环境sudo apt-get install phpmyadmin sudo apt-get install php-mbstring sudo apt-get
- Spring AOP技术(基于AspectJ)的Annotation开发
- [二分答案 2-SAT验证 前后缀优化建图] Codeforces 587D #326 (Div. 1) D. Duff in Mafia
- 信息系统服务管理 典型试题分析
- 能量获取 Energy
- MySQL limit实现分页(五)
- Java进阶-数据类型
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
- HTML标签之音频、视频标签
- 前端之JQuery