1、Maven依赖
<!-- spring AOP 切面-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.2.5</version>
</dependency>
2、SpringAOP配置
2.1 基于XML的配置(来源:spring aop两种配置方式)
<?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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
"><!-- 要添加最后2行 -->
<context:annotation-config />
<context:component-scan base-package="com.oumyye"/> <!-- 自动扫描 -->
<aop:aspectj-autoproxy/> <!-- 要添加本行 -->
</beans>
2.2 基于注解方式的配置
采用纯注解的方式来配置就比xml配置较为简单一些,只需要在项目中的Spring配置类上添加下面注解即可。
@EnableAspectJAutoProxy //启用自动代理功能(相当于xml配置中这句话:<aop:aspectj-autoproxy/>)
3、aop实现
添加一个类文件,需要添加注解@Aspect
和@Component
。
/**
* Spring Aop编程,主要是为了实现插拔式代码的实现,当某个状态开启时,利用切面对service层的返回结果进行干预转换,给controller层使用
* ClientAspect当前这个类其实主要功能是策略安全域的扩展,当策略安全域开启时,在这里面做数据的拦截和转换,如果关闭,则直接返回service层的结果
* 这样做的好处是不改变之前的代码,根据开启状态实现代码的可插拔式
*/
@Aspect
@Component(value = "testAspect")
public class testAspect {
/**
* execution (* com.test.service.impl..*.*(..))
* 第一个*号:表示返回类型,*号表示所有的类型;
* 两个句点..表示当前包和当前包的所有子包;
* 第二个*号:表示类名,*号表示所有的类。
* *(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
*/
/**
* 调用查询终端接口的时候,controller层会调用service,当service对应的方法被调用的时候,
* aop会进行监听,然后对获取到的数据进行处理,如果安全域没有开启,增直接把service返回给controller,
* 否则对数据进行过滤,将属于自己管理下的安全域的终端设备数据返回给controller,
* 根据开启关闭来返回数据,不会干预之前写好的controller,实现插拔式
*
* @param pjp 执行的方法
* @return 返回service的方法结果
*/
@Around("execution(* com.test.pageQuery(..)) || execution(* com.test.list(..)))")
// @Around("execution(* com.test.service..*.*(..))")
public Object clientSecurityShow(ProceedingJoinPoint pjp) throws JsonException {
try {
result = pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
throw new JsonException(throwable.getMessage());
}
// 判断条件,只有当这个条件满足的时候,对result的返回结果,也就是service返回的结果进行干预处理,返回给controller层
// 如果不满足,则直接返回result,也就是service的结果直接给controller,
// 这样就实现了可插拔式代码的实现
if(...){
// 这里对result做一些需要的处理
} else {
// 策略安全域关闭的时候,直接返回原来的结果
return result;
}
return result;
}
}
4、总结
通过SpringAOP的方式,在不修改原来代码的情况下,对service层的返回结果进行干预,实现一些项目后期添加的功能,这样避免对源代码进行了修改,又实现了插拔式,可用可不用的实现。