1相关术语
1.1Joinpoint(连接点)service接口
所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。
1.2Pointcut(切入点): serviceimp
所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
1.3 Advice(通知/增强): 业务层的前后增强通知
所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
1.4 Introduction(引介): 暂时不知道
引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方
法或 Field。
1.5 Target(目标对象):被代理的目标对象
代理的目标对象
1.6 Proxy(代理):
一个类被 AOP 织入增强后,就产生一个结果代理类。
1.7 Aspect(切面):
是切入点和通知(引介)的结合。
2:xml配置
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="logger" class="com.hp.util.Logger"/>
<bean class="com.hp.service.Imp.AccountServiceImp" id="accountServiceImp"/>
配置切入点表达式 id属性用于指定表达式的唯一标识。expression属性用于指定表达式内容
此标签写在aop:aspect标签内部只能当前切面使用。
它还可以写在aop:aspect外面,此时就变成了所有切面可用
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.hp.service.Imp.*.*(..))"/>
<!–配置切面 –>
<aop:aspect id="logAdvice" ref="logger">
<aop:after method="beforePrintLog" pointcut-ref="pt1"/>
</aop:aspect>
</aop:config>-->
</beans>
3 注解配置 (一定要开启aop支持)
<!--包扫描-->
<context:component-scan base-package="com.hp"/>
<!-- 配置spring开启注解AOP的支持 -->
<aop:aspectj-autoproxy/>
@Component("logger")
@Aspect //指定该类为切面类
@Before 前置
@AfterReturning 后置
@AfterThrowing 异常
@After 最终
//环绕通知
/**
* 环绕通知
* 问题:
* 当我们配置了环绕通知之后,切入点方法没有执行,而通知方法执行了。
* 分析:
* 通过对比动态代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,而我们的代码中没有。
* 解决:
* Spring框架为我们提供了一个接口:ProceedingJoinPoint。该接口有一个方法proceed(),此方法就相当于明确调用切入点方法。
* 该接口可以作为环绕通知的方法参数,在程序执行时,spring框架会为我们提供该接口的实现类供我们使用。
*
* spring中的环绕通知:
* 它是spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式。
*/
@Around("pub()")
public Object aroundPingLog(ProceedingJoinPoint pjp) {
Object rtValue = null;
Object[] args = pjp.getArgs();//得到方法执行所需的参数
try {
System.out.println("前置----通知Logger类中的beforePrintLog方法开始记录日志了。。。");
rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法)
System.out.println("后置----通知Logger类中的beforePrintLog方法开始记录日志了。。。");
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("异常----通知Logger类中的beforePrintLog方法开始记录日志了。。。");
} finally {
System.out.println("最终----通知Logger类中的beforePrintLog方法开始记录日志了。。。");
}
return rtValue;
}
eg: Aop管理事务案例(基于ssm的事务管理)
<?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:tx="http://www.springframework.org/schema/tx"
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/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.itheima.service"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务属性-->
<!-- 配置事务的属性
isolation:用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。
read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。
timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true" propagation="SUPPORTS" />
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txadvice" pointcut-ref="pt1"/>
</aop:config>
</beans>