Spring AOP(二)--注解方式
本文介绍通过注解@AspectJ实现Spring AOP,这里要重点说明一下这种方式实现时所需的包,因为Aspect是第三方提供的,不包含在spring中,所以不能只导入spring-aop的包,为了安全起见我导入的包有(我是maven方式添加依赖):
步骤如下:
一、创建连接点
spring是方法级别的拦截器,所以连接点就是某个类中的某个方法,从动态代理的角度来看就是将要拦截的方法织入AOP通知。
1⃣️创建一个接口
public interface EmployeeService { public void getEmployeeInfo(Employee employee); public void getEmployeeSex(Employee employee);
}
这个接口中提供了两个方法,后续会用来测试连接点的概念,因为只有将方法织入到AOP才会执行完整的拦截流程。
2⃣️创建接口实现类,增加注解@Component
@Component
public class EmployeeServiceImpl implements EmployeeService { @Override
public void getEmployeeInfo(Employee employee) {
System.out.println("name:" + employee.getUsername() + ";sex:" + employee.getSex());
} @Override
public void getEmployeeSex(Employee employee) {
System.out.println("性别:"+employee.getSex());
}
}
二、创建切面
创建好了连接点之后就可以创建切面了,它就相当于是一个拦截器,在spring中只要使用@Aspect注解一个类,spring ioc容器就会将它视为一个切面处理。
package com.hyc.aop.aspect; 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.DeclareParents;
import org.aspectj.lang.annotation.Pointcut; import com.hyc.pojo.Employee; /**
* 定义一个切面
*
* @Aspect 该注解表示这个类就是一个切面了
*/
@Aspect
public class EmployeeAspect { /**
* 定义一个切点,通知aop什么时候启动拦截并织入对应流程
* 注意以下几点:
* 1、方法返回类型* 和方法之间有空格
* 2、在下面的四个方法中引用这个切点时方法名要加括号
* 3、execution正则表达式中的方法就是一个连接点,将代理对象和切面相连,如果不定义这个连接点,则不会将代理对象的方法和切面相连
*/
@Pointcut("execution(* com.hyc.aop.aspect.EmployeeServiceImpl.getEmployeeInfo(..))")
public void getInfo() { } @Before("getInfo()")
public void before() {
System.out.println("before:代理方法执行之前");
} @After("getInfo()")
public void after() {
System.out.println("after:代理方法执行完毕");
} @AfterReturning("getInfo()")
public void afterReturning() {
System.out.println("afterReturning:代理方法执行完毕,执行成功");
} @AfterThrowing("getInfo()")
public void afterThrowing() {
System.out.println("afterThrowing:代理方法执行完毕,执行过程出现异常");
}
}
上面的代码中红色加粗部分所代表的意思如下:
- @Aspect注解:告诉spring,这个类是一个切面;
- @Pointcut注解:定义一个切点,并告诉AOP什么时候启动拦截并织入对应流程;
- @before、@after、@afterReturning、@afterThrowing分别是四种通知,它们可以引用之前定义的切点,也可以有自己的切点;
有必要解释一下定义切点注解@Pointcut中的内容:
@Pointcut("execution(* com.hyc.aop.aspect.EmployeeServiceImpl.getEmployeeInfo(..))")
在上面的注解中,定义了execution的正则表达式,spring是通过这个正则表达式判断是否需要拦截你所定义的方法,即被代理对象的方法。
- execution:代表执行方法的时候会触发;
- *:代表方法的返回类型任意;
- com.hyc.aop.aspect.EmployeeServiceImpl:被代理类的全限定名,注意它和前面的返回类型*之间有一个空格;
- getEmployeeInfo:被拦截方法名称;
- (..):方法中的参数,类型任意;
通过上面的描述,上述注解及内部正则表达式的意思就是:全限定名为com.hyc.aop.aspect.EmployeeServiceImpl的类中的getEmployeeInfo方法被当做一个切点,当程序执行这个方法的时候对它进行拦截,这样就能按照AOP通知的规则把这个方法织入流程中。
三、创建配置类,采用注解java配置
/*
* 定义一个配置类,通过java配置的方式获取切面
*/
@Configuration
@ComponentScan(basePackages= {"com.hyc.aop.aspect","com.hyc.pojo"})
@EnableAspectJAutoProxy //自动代理,代替了动态代理的实现
public class AspectConfig {
//返回一个切面
@Bean
public EmployeeAspect getAspect() {
return new EmployeeAspect();
} }
这个配置就是之前介绍过的注解方式装配bean的配置方法,不过对AOP有效的注解是@EnableAspectJAutoProxy,从字面意思理解它是开启了切面自动代理功能,其实就是启用了AspectJ框架的自动代理,这样spring就会生成一个代理对象,进而使用AOP,其中的getAspect方法是生成了一个切面。
四、测试
完成了上面的配置之后,我就可以进行测试了,测试方法如下:
@Test
public void testAopByConfig() {
@SuppressWarnings("resource")
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class);
EmployeeService es = (EmployeeService) context.getBean(EmployeeService.class);
Employee employee = (Employee) context.getBean("employee");
es.getEmployeeInfo(employee);
employee = null;
es.getEmployeeInfo(employee);
}
上面的单元测试方法中红色部分:
第四行:首先是获取配置类的上下文,此时已经启动AspectJ的自动代理,并生成了一个切面;
第五行:通过上下文就能生成一个代理对象,如果被代理类有接口则采用jdk动态代理,否则就是CGLIB动态代理;
第七行:测试方法,因为employee不为空,所以可以正常返回,并执行afterReturning方法;
第八、九行:将employee设置为null,执行过程出现异常,所以会执行aferThrowing方法;
查看测试结果:
从上面的运行结果来看,完全符合刚开始的流程图:
1、首先执行before方法;
2、执行被代理对象的方法;
3、执行完被代理对象方法后,不管成功与否都会执行after方法;
4、如果被代理对象的方法正常返回,则执行afterReturning方法,如果返回异常,则执行afterTrowing方法(结果中的afterException是书写错误,其实都一个意思啦
Spring AOP(二)--注解方式的更多相关文章
- spring aop 使用注解方式总结
spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...
- spring AOP自定义注解方式实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- Spring AOP的注解方式实现
spring也支持注解方式实现AOP,相对于配置文件方式,注解配置更加的轻量级,配置.修改更加方便. 1.开启AOP的注解配置方式 <!-- 开启aop属性注解 --> <aop:a ...
- perf4j+spring+aop 配置 注解方式
今天将perf4j基于spring aop方式进入了接入,接入方法还是比较简单.具体配置如下: logback.xml <!--perf4j配置--> <appender name= ...
- Spring AOP(注解方式)
配置文件: xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org ...
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
- 跟着刚哥学习Spring框架--通过注解方式配置Bean(四)
组件扫描:Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的组件. 特定组件包括: 1.@Component:基本注解,识别一个受Spring管理的组件 2.@Resposit ...
- (转)利用Spring AOP自定义注解解决日志和签名校验
一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...
- spring AOP自定义注解 实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
随机推荐
- day 81 Vue学习二之vue结合项目简单使用、this指向问题
Vue学习二之vue结合项目简单使用.this指向问题 本节目录 一 阶段性项目流程梳理 二 vue切换图片 三 vue中使用ajax 四 vue实现音乐播放器 五 vue的计算属性和监听器 六 ...
- 动态调整Log4j日志级别
log4j2.xml配置文件中支持配置monitorInterval参数,检测到配置改变后重新加载,达到动态调整日志级别的效果. 故调整日志级别无须手动重启服务. log4j2.xml配置文件示意: ...
- Spring事物管理机制简单学习
首先spring并不直接管理事物,而是提供了多种事物管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现. Spring管理事物的接口是org.s ...
- 第三周——重新clone项目、配置并编译
重新clone项目的原因 因为实习尚未有公司邮箱,使用qq邮箱没有权限提交代码,因此使用晶哥的账号和gitlab, 但是git clone项目默认会关联账号(可能有某些配置项,但是找不到), idea ...
- SQL的语言分类
SQL的语言分类 DQL DQL(Data Query Language):数据查询语言 select DML DML(Data Manipulate Language):数据操作语言 insert ...
- 使用Excel表格导入数据到Oracle表
在工作中我们会遇到将通过数据手动录入到系统中的需求,如果数据量比较小,那么手动输入是可行的,倘若数据量很大,那么这些数据手动录入将会是一个很大的工作量,为了简化这个手动录入的操作流程,我们可以使用Ex ...
- Python版本OpenCV安装配置及简单实例
# 2018-06-03 # 1. Python下载:https://www.python.org/downloads/ 选择对应平台对应版本的的Python进行安装. 2. Python版OpenC ...
- ASCII专用测试字符串
这段是废话: 在很多时候不同语言所写的不同终端中 经常会有字符串转码的问题 常用一下字符串测试不同终端的输出可以快速匹配和修改默认转码 正文: !""""#$% ...
- apache tomcat 一个网站多域名的实现方法
因此处是进行多域名设置,所以 Apache 与 tomcat的结合没有详述,此处只是设置多域名的方法 windows下 C:\WINDOWS\system32\drivers\etc 文件夹内 hos ...
- vuex结合vue-cookies的使用
一.创建vuex import Vue from 'vue' import Vuex from 'vuex' import cookie from "vue-cookies" Vu ...