AOP通知
-
前置通知@Befor:目标方法之前执行
@Aspect // 标记为了切面类 @Component // 必须声明为 Spring 的 bean public class LogAspect { // 实现方法用时 切点表达式 // 前置通知 @Before("execution(* com.example.c4_aop.UserService.*(..) )") public void before(JoinPoint joinPoint) { // 记录当前方法的方法名,参数 String methodName = joinPoint.getSignature().getName(); // 参数 Object[] args = joinPoint.getArgs(); System.out.println("当前执行的方式是"+methodName+":参数"+Arrats.toString(args)); } }
-
后置通知@After:目标方法之后执行
-
异常通知@AfterThrowing:目标方法出现了异常执行
-
返回通知@AfterReturning:目标方法返回值执行
-
环绕通知@Around:可以把代码增强在目标方法的任意地方,更通用
切点表达式
切点表达式的抽取
@Pointcut("execution(* com.example.c4_aop.UserService.*(..) )") public void poincut(){}
这样,只需要在通知中写入此方法即可,如:
@Around("pointcut()")
execution格式:用于匹配方法执行连接点。这是使用Spring AOP时使用的主要切点标识符。可以匹配到方法级别
execution(modifiers-pattern? //访问修饰符,问号代表可写可不写 ret-type-pattern //方法返回值 declaring-type-pattern?name-pattern(param-pattern) //类名.方法名(方法参数) throws-pattern?) //抛出异常类型
@annotation:限制匹配连接点(在Spring AOP中执行的方法具有给定的注解)
需求:需要记录每个方法详细作用,并且记录数据库日志表
Log方法
@Retention(RetentionPolicy.RUNTIME) // 注解的保留 @Target({ElementType.METHOD,ElementType.TYPE}) // 可以标记的地方 public @interface Log { }
// Poincut 所有的方法有log注解都会匹配 // 如果要在通知的参数中绑定注解就不能单独抽取 // 如果要在通知的参数中绑定注解,声明就是参数名了,不是注解类型! @Pointcut("@annotation(Log)") public void pointcutAnnotation(){}
18.Spring事务
什么是事务:一组关联的数据库操作;要么都成功,要么都失败,保证业务操作完整性的一种数据库机制
ACID四大特性:原子性,一致性,隔离性,持久性
spring要操作数据库的话:要导入spring-jdbc
spring-dao.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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd" //DataSource:使用Spring的数据源替换Mybatis的配置,这里使用Spring提供的JDBC <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8" <property name="username" value="root"/> <property name="password" value="123456"/> </bean> //sqlSessionFactory <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"? <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" vlaue="classpath:com/kuang/mapper/*xml"/> </bean> //SqlSessionTemplate:就是我们使用的sqlSession <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> </beans>
Spring声明式事务
//配置声明式事务 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> //结合AOP实现事务的织入 //配置事务通知 <tx:advice id="txAdvice" transaction-manager="transactionManager"> //给那些方法配置事务 //配置事务的传播特性 <tx:attributes> <tx:method name="add" propagation="REQUIRED"/> <tx:method name="update" propagation="REQUIRED"/> <tx:method name="query" read-only="true"/> </tx:attributes> </tx:advice> //配置事务切入 <aop:config> <aop:pointcut id="txPointCut" experssion="execution(*com.zkw.mapper.*.*(..))" <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>