Spring:基于xml和注解的aop
程序员文章站
2024-03-24 12:55:10
...
1、导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--用于解析切入点表达式的jar包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
2、建立通知类
将方法(主要是业务逻辑层的方法)中的共性代码抽取出来放到通知类中统一管理。
3、配置通知
配置文件中添加aop的约束。先配置ioc(spring的其它功能都需要基于ioc),再配置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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--先配置service的ioc-->
<bean id="accountService" class="cao.zhanpeng.service.impl.AccountServiceImpl"/>
<!--配置通知类的ioc-->
<bean id="log" class="cao.zhanpeng.utils.Logger"/>
<!--开始配置aop-->
<aop:config>
<!--配置切面,id表示该切面唯一标识符,ref用于指定通知类bean的id-->
<aop:aspect id="logShow" ref="log">
<!--配置通知类型,aop:before表示前置通知
method指定通知类中哪个方法是前置通知(哪个是通知?)
pointcut指定切入点表达式,表示对业务层的哪些方法进行通知(对谁通知?)
-->
<aop:before method="printLog" pointcut="execution(public void cao.zhanpeng.service.impl.AccountServiceImpl.saveMoney())"/>
</aop:aspect>
</aop:config>
</beans>
可以将切入点表达式独立出来
<!--将切入点表示式独立出来
如果放在切面内,只能当前切面引用
如果放在切面外,可以多个切面共用
-->
<aop:pointcut id="pt1" expression="execution(* cao.zhanpeng.service.impl.*.*(..))"/>
<!--再引用-->
<aop:before method="printLog" pointcut-ref="pt1"/>
切入点表达式
- 关键字:execution(表达式)
- 表达式:访问修饰符 返回值 通知目标类的全类名.方法名(参数列表)
- 访问修饰符可以省略
- 通常会将范围锁定到业务层的实现类包下
<!--星号表示任意通配符,双点..可以表示任意数量的通配符-->
* com.zanpng.service.impl.*.*(..)
全通配写法如下(了解)
* *..*.*(..)
通知类型
aop:before,前置通知
aop:after-returning,后置通知
aop:after-throwing,异常通知,和后置通知互斥
aop:after,最终通知
aop:around,环绕通知
注解实现aop
1、配置环境
需要在applicationContext.xml文件导入context约束,配置ioc注解扫描,并直接使用以下标签开启aop注解。
<aop:aspectj-autoproxy/>
2、使用注解
在通知类上除了写上ioc注解,还要加上@Aspect注解,表示当前类是一个通知类。还要在对应的方法上使用如**解
@Before注解,前置通知
@AfterRunning注解,后置通知
@AfterThrowing注解,异常通知
@After注解,最终通知
@Around注解,环绕通知
定义一个空语句体的方法,使用@Pointcut注解传递切入点表达式,并且在其他注解中传递该方法,注意括号别忘了。
@Pointcut("execution(* cao.zhanpeng.service.impl.*.*(..))")
private void pt1(){}
@Before("pt1()")
public void beforePrintLog(){……}
在使用注解实现aop时,spring会出现一些执行顺序上的问题。所以如果要用注解,还是使用环绕通知来手动指定较好。环绕通知需要自己实现动态代理的代码,根据位置手动指定某个通知为何种类型。
- spring框架提供了一个接口ProceedingJoinPoint,该接口可以作为通知类中环绕通知方法的参数,执行时spring会自动帮我们创建实现类对象,比如叫pjp。
- pjp.getArgs()可以获取方法执行所需的参数。
- ProceedingJoinPoint接口中有一个方法proceed(),此方法可以明确调用切入点方法(对应反射中的invoke方法),传递获取的参数即可。
@Around("pt1()")
public Object aroundPrintLog(ProceedingJoinPoint pjp){
Object rtValue = null;
try{
Object[] args = pjp.getArgs();
……前置通知代码块……
rtValue = pjp.proceed(args)
……后置通知代码块……
}catch{
……异常通知代码块……
}finally{
……最终通知代码块……
}
}
有了环绕通知,就不能让其他的通知起作用了,否则会产生冲突。
推荐阅读
-
Spring:基于xml和注解的aop
-
Spring:基于xml和注解的事务
-
Spring基于xml配置与注解驱动开发(一)
-
Spring中xxx-servlet.xml和applicationContext.xml的认识 applicationcontextspringmvc
-
一个基于spring aop实现的日志系统 博客分类: spring
-
一个基于spring aop实现的日志系统 博客分类: spring
-
基于注解实现spring AOP 博客分类: spring框架 springaop
-
Spring与Mybatis基于注解整合Redis的方法
-
Spring使用AspectJ注解和XML配置实现AOP
-
Spring使用AspectJ注解和XML配置实现AOP