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 ...
随机推荐
- JavaScript中的浏览器对象模型
浏览器对象模型 1.浏览器引入JavaScript 1.直接在HTML文件中引入 首先第1种方式就是直接在HTML文档里面引入JavaScript代码.在维护一些老项目的时候,经常 可以看到J ava ...
- 谈谈域名DNS的缓存问题
可以从很多地方看到,许多刚开始做站的朋友,对域名设置方面的知识原理一知半解,以至于为了某些测试需要,经常对域名解析大动干戈.今天改个A记录,明天又换个NS.又或者,在迁移域名,迁移网站的时候的时候由于 ...
- shell启停服务脚本模板
一. 启动脚本模板:符合幂等性 如果该服务已经启动,再次调用该脚本,不会报错,也就是说可以反复多次调用,另外启动成功返回 一个参数,提供给自动发布平台校验该服务是否启动 #!/bin/bash ins ...
- Java性能优化的50个细节,我必须分享给你!
来源:blog.csdn.net/dongnan591172113/article/details/51790428 ;i<list.size();i++) ,len=list.size();i ...
- 06_mybatis关系映射
1.数据库表分析 表与表之间的业务关系: 在分析表与表之间的业务关系时需要建立 在某个业务意义基础上去分析; 先分析数据级别之间有关系的表之间的业务关系; usre和orders: use ...
- 13-5-let和()的作用域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- java ajax长连接请求服务器数据
Servlet 3.0笔记之异步请求Comet推送长轮询(long polling)篇 Comet另一种形式为长轮询(long polling),客户端会与服务器建立一个持久的连接,直到服务器端有数据 ...
- 使用Image作为BackgroundColor 使用
https://www.hackingwithswift.com/example-code/uicolor/how-to-use-an-image-for-your-background-color- ...
- mac brew nginx php php-fpm xdebug
/usr/local/opt/nginx/bin/nginx -v brew services restart nginx sudo /usr/local/sbin/php-fpm --fpm-con ...
- 爆表!猜猜这个大会的IQ总值有多高?
“人人可及的未来,同样存在于「日拱一卒」的琐碎生活当中,那也是技术对生活最为直观的改变和演进.” “以通神明之德,以类万物之情”,这句来自<易经>的话,放到现今也合宜. 人类掌控事物发展的 ...