本文介绍通过注解@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(二)--注解方式的更多相关文章

  1. spring aop 使用注解方式总结

    spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...

  2. spring AOP自定义注解方式实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  3. Spring AOP的注解方式实现

    spring也支持注解方式实现AOP,相对于配置文件方式,注解配置更加的轻量级,配置.修改更加方便. 1.开启AOP的注解配置方式 <!-- 开启aop属性注解 --> <aop:a ...

  4. perf4j+spring+aop 配置 注解方式

    今天将perf4j基于spring aop方式进入了接入,接入方法还是比较简单.具体配置如下: logback.xml <!--perf4j配置--> <appender name= ...

  5. Spring AOP(注解方式)

    配置文件: xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org ...

  6. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

  7. 跟着刚哥学习Spring框架--通过注解方式配置Bean(四)

    组件扫描:Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的组件. 特定组件包括: 1.@Component:基本注解,识别一个受Spring管理的组件 2.@Resposit ...

  8. (转)利用Spring AOP自定义注解解决日志和签名校验

    一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...

  9. spring AOP自定义注解 实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

随机推荐

  1. VS2010-MFC(MFC常用类:CString类)

    转自:http://www.jizhuomi.com/software/228.html CString类简介 CString类作为MFC的常用类,当之无愧.可以这样说,只要是从事MFC开发,基本都会 ...

  2. JS程序的基本语法

    JS程序的基本语法 JS是区分大小写的.如:Name和name是两个变量 JS中每一条语句,一般以英文下的分号(;)结束.这个分号不是必须的.为了向PHP兼容,最好加上分号. 运算符和变量,以及操作之 ...

  3. ThinkPHP5的简单使用

    目录的介绍 thinkphp5 的控制器的创建 第一步:新建一个控制器 第二步:admin.php控制器内容如下 第三步:如何显示模型页面 第四步:显示模板页面 第五步:定义模板变量 第六步:运行结果 ...

  4. Cocos2d-x通过Jni实现C++与Java相互调用

    在cocos2dx项目中与运营平台(java sdk)对接时使用了JNI. 通过C++调用Java 在JniUtil.h文件中如下实现: #ifndef _JNIUTIL_H_ #define _JN ...

  5. Java程序员注意:Tomcat Get请求的巨坑!

    Tomcat8.5,当Get请求中包含了未经编码的中文字符时,会报以下错误,请求未到应用程序在Tomcat层就被拦截了. Tomcat报错: java.lang.IllegalArgumentExce ...

  6. CSS清除默认边距

    body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquo ...

  7. Xcode9.4.1官方下载链接地址

    More Downloads for Apple Developershttps://developer.apple.com/download/more/ Xcode 9.4.1https://dow ...

  8. AbstractByteBuf 源码分析

    主要成员变量 static final ResourceLeakDetector<ByteBuf> leakDetector = new ResourceLeakDetector<B ...

  9. Arrays.asList()使用的问题

    在java语言中,把数组转换成List集合,有个很方便的方法就是 List<String> list = Arrays.asList("a","b" ...

  10. Luogu P2458 [SDOI2006]保安站岗(树形dp)

    P2458 [SDOI2006]保安站岗 题意 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下 ...