基于注解的AOP配置 使用配置类而不使用XML文件(代替bean.xml)对spring进行配置

配置文件

spring配置文件中的约束

<?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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

在spring配置文件中配置Spring创建容器时要扫描的包

 <context:component-scan base-package="com.itheima"></context:component-scan>

 在spring配置文件中开启spring对注解AOP的支持

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

在pom.xml中添加依赖

<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
</dependency>

若不使用配置文件而使用配置类配置Spring

使用配置类而不使用XML文件(代替bean.xml)对spring进行配置

@Configuration //指定当前类是一个spring配置类
@ComponentScan(basePackages="com.itheima") // 配置spring创建容器时要扫描的包
@EnableAspectJAutoProxy //配置spring开启注解AOP的支持
public class SpringConfiguration { }

注解配置

把资源使用注解配置

把通知类也使用注解配置

在通知类上使用@Aspect注解声明为切面

在增强的方法上使用注解配置通知

  @Before

    作用: 把当前方法看成是前置通知。

    属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用。

//开启事务
@Before("execution(* com.itheima.service.impl.*.*(..))") public void beginTransaction() { try { dbAssit.getCurrentConnection().setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } }

  @AfterReturning

    作用: 把当前方法看成是后置通知。

    属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用

  @AfterThrowing

    作用: 把当前方法看成是异常通知。

    属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用

  @After

    作用: 把当前方法看成是最终通知。

    属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用

环绕通知注解配置

  @Around

    作用: 把当前方法看成是环绕通知。

    属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用。

未使用切入点表达式注解, 直接在@Around中指定切入点表达式

/** * 环绕通知 
* @param pjp 
* @return 
*/ 
@Around("execution(* com.itheima.service.impl.*.*(..))")
public Object transactionAround(ProceedingJoinPoint pjp) { 
  //定义返回值 
  Object rtValue = null;
  try {
    //获取方法执行所需的参数 
    Object[] args = pjp.getArgs();
    //前置通知:开启事务 
    beginTransaction(); 
    //执行方法
    rtValue = pjp.proceed(args); 
    //后置通知:提交事务 
    commit(); 
  }catch(Throwable e) { 
    //异常通知:回滚事务
    rollback(); 
    e.printStackTrace();
  }finally { 
    //最终通知:释放资源 
    release(); 
  }
  return rtValue;
}    

使用切入点表达式注解, 在@Around中指定切入点表达式引用

  @Pointcut

  作用: 指定切入点表达式

  属性:value:指定表达式的内容

  使用时

    @Around("pt1()")    千万别忘了写括号

@Pointcut("execution(* com.itheima.service.impl.*.*(..))") 
private void pt1() {}

@Around("pt1()")//注意:千万别忘了写括号
public Object transactionAround(ProceedingJoinPoint pjp) { 
......
.....
}

 注意:

在使用除环绕通知的其他通知时,他们的顺序并不是一定的最终通知会执行优先于后置通知与环绕通知,

因此当我们使用最终通知来释放一些资源的时候,可能会出现资源已经释放,但是后置通知仍在使用的情况,这时就会出现错误,

因此我们遇到这种情况时要特别注意,为了保证通知的顺序,我们必要的使用环绕通知,环绕通知的执行顺序是一致的。

猜你喜欢

转载自www.cnblogs.com/mkl7/p/10698294.html