那么,既然学习了代理衍生出的拦截器,那么我们便可以运用在我们创建好的spring
工程上
还记得那个MVC和注解开启的项目吗。
既然是AOP
的,是面向切面的,那么,我们接下来,就是建立了其中一个A
,建立一个切面,功能是拦截器
1、新建切面模块
我们新建一个文件夹,名为aspect
,用来存放不同功能的切面文件
2、下载相应的依赖
因为要在spring
建立切面功能,我们需要去maven
安装对应的依赖
https://mvnrepository.com/
搜索aspect
,找到AspectJ Runtime
、AspectJ Weaver
,复制相应的依赖文件到pom.xml
<!-- spring aop 面向切面编程依赖 -->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
<scope>runtime</scope>
</dependency>
3、建立拦截器
思想和代码,和我们自己建立的那个拦截器很相像的,只要把一些参数改为spring
封装好的对象就好
package net.duck.spring.ioc.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
*
* spring通知
*
* 在某个方法的生命周期拦截增强的方法
* 切面:通知的集合
* 连接点:要增强的方法
* 切点:所有连接点的集合
*
* @author PigIsDuck
*
*/
public class MyAspect {
/**
*
* 前置通知
*
* 方法执行之前
* 如果返回为真true,那么后面的逻辑继续
* 返回为假false, 则方法不会执行
*
* @param jp 连接点
* @return
*/
public boolean before(JoinPoint jp) {
System.out.println("before");
return true;
}
/**
*
* 环绕通知
*
* 方法在执行的时候
* 会得到方法执行的结果
* 方法如果真的执行了,只能在环绕通知里面执行
*
* @param pjp 连接点
* @return
* @throws Throwable
*/
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around");
Object result = pjp.proceed();
return result;
}
/**
* 后置通知
*
* 方法执行之后,在执行这个节点的时候,方法已经有返回值了,所以可以接收返回值的结果
*
* @param result 方法执行的结果
* @param pjp 连接点
*/
public void afterReturning(JoinPoint jp, Object result) {
System.out.println("afterReturning");
}
/**
*
* 异常通知
*
* 方法抛出异常之后
*
* @param e 方法所抛出的异常
* @param pjp 连接点
*/
public void afterThrowing(JoinPoint jp, Exception e) {
System.out.println("afterThrowing");
}
/**
*
* 最终通知
*
* 最终,方法不管执行与否,都会被调用
*
* @param pjp 连接点
*/
public void after(JoinPoint jp) {
System.out.println("after");
}
}
4、配置拦截器
在项目配置文件applicationContext.xml
里,将拦截器注册进去,然后找到其他文件,为文件方法配置拦截器
<!-- 配置切面 -->
<bean id="myAspect" class="net.duck.spring.ioc.aspect.MyAspect"></bean>
<aop:config>
<aop:aspect ref="myAspect">
<!-- 切点表达式 筛选方法签名 execution() * net.duck..*.service.impl.*.*(..) -->
<aop:pointcut expression="execution(* net.duck..*.service.impl.*.*(..))" id="pc"/>
<aop:before method="before" pointcut-ref="pc"/>
<aop:around method="around" pointcut-ref="pc"/>
<aop:after-returning method="afterReturning" pointcut-ref="pc" returning="result"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pc" throwing="e"/>
<aop:after method="after" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
expression="execution(* net.duck..*.service.impl.*.*(..))"
,这句话的意思是:扫描
net.duck
开头,service.impl
结尾的包的所有文件、所有方法
5、使用
既然我们配置好拦截器,并且注册了,那么拦截器就会在spring
上自动运行,所以主代码正常使用就好
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserController controller = (UserController) context.getBean("userController");
controller.queryAllUser();
结果:
init MockServlet1
before
around
net.duck.spring.ioc.dao.UserDao@5c5eefef
afterReturning
after
User [username=duck, password=123456]
User [username=pig, password=1asd56]