zoukankan      html  css  js  c++  java
  • spring学习5:基于注解实现spring的aop

    spring学习5:基于注解实现spring的aop

    上一节学习了spring aop的基本概念和如何基于xml配置来实现aop功能。这一节来学习下如何用注解实现aop

    一、基于注解+xml实现

    上节中虽然也使用的是注解+xml,但只是把bean的配置用注解来实现,aop相关的切面,切入点等配置都是在spring的xml配置文件中实现的。

    <!--通知类使用注解配置-->
        <!--使用aop:config 来声明aop的配置-->
        <aop:config>
            <aop:aspect id="transactionAspect" ref="transactionManager">
                <!--这个切入点表达式表示com.lyy.service及其子包中的任意类的任意方法-->
                <aop:pointcut id="servicePointcut" expression="execution(* com.lyy.service..*.*(..))"/>
                <!--在切面的内部配置通知的类型-->
                <!--配置前置通知-->
                <aop:before method="startTransaction" pointcut-ref="servicePointcut"/>
                <!--后置通知-->
                <aop:after-returning method="commit" pointcut-ref="servicePointcut"/>
                <!--配置异常通知-->
                <aop:after-throwing method="rollBack" pointcut-ref="servicePointcut"/>
            </aop:aspect>
        </aop:config>
    

    这一节我们首先来实现把aop的配置也用注解来实现。

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

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

    <!--开启spring对注解aop的支持-->
    <aop:aspectj-autoproxy/>
    

    1.2 把通知类用注解配置到容器中,并用注解声明为切面

    在通知类上写上@Aspect注解,把这个类声明为切面类

    1.3 定义切入点表达式

    在通知类中定义一个方法,打上@Pointcut注解,说明这个方法用来定义切入点表达式,方法名代表表达式的名称

    	//用来定义切入点表达式的方法,方法名就是切入点表达式的名称
        @Pointcut("execution(* com.lyy.service..*.*(..))")
        public void pt1(){
    
        }
    

    1.4 定义通知

    在对应的方法名上打上通知类型对应的注解,定义通知

    
    /**
     * 通知类
     */
    @Component
    @Aspect//把当前类声明为切面类
    public class TransactionManager {
    
        @Autowired
        private ConnectionUtils connectionUtils;
    
        @Before("pt1()")
        public void startTransaction(){
            Connection connection = connectionUtils.getConnection();
            try {
                System.out.println("开启事务");
                connection.setAutoCommit(false);
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("开启事务失败,"+e.toString());
            }
        }
    
        /**
         * 提交事务
         */
        @AfterReturning("pt1()")//后置通知
        public void commit(){
            Connection connection = connectionUtils.getConnection();
            try {
                System.out.println("提交事务");
                connection.commit();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("提交事务失败,"+e.toString());
            }
        }
    
        /**
         * 回滚事务
         */
        @AfterThrowing("pt1()")//异常通知
        public void rollBack(){
            Connection connection = connectionUtils.getConnection();
            try {
                System.out.println("业务异常,事务回滚");
                connection.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("回滚事务失败,"+e.toString());
            }
        }
    
        /**
         * spring aop的环绕通知,手动控制增强代码的执行时机
         * @param proceedingJoinPoint
         * @return
         */
        public Object around(ProceedingJoinPoint proceedingJoinPoint){
            Object returnValue=null;
            try {
                //开启事务
                startTransaction();
                Object[] args = proceedingJoinPoint.getArgs();
                returnValue = proceedingJoinPoint.proceed(args);
                //提交事务
                commit();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                //回滚事务
                rollBack();
            } finally {
                //最终通知
            }
            return returnValue;
        }
    
        //用来定义切入点表达式的方法,方法名就是切入点表达式的名称
        @Pointcut("execution(* com.lyy.service..*.*(..))")
        public void pt1(){
    
        }
    

    二、基于纯注解实现

    首先需要在配置类上用一个注解@EnableAspectJAutoProxy开启对注解aop的支持,然后其余的步骤和上边的2、3、4相同。

    三、多个aop的执行顺序

    多个aop切入同一个方法时,默认的执行顺序是随机的,可以通过配置order来设置执行顺序

    1.xml配置

    在配置切面时加上order属性

    <aop:aspect ref="aopBean" order="0">    
    

    2.注解配置

    在切面类上加@Order注解

    注意order越小,顺序越早

    3.注意

    先执行的aop方法一定后结束

    可以理解为spring aop就是一个同心圆,要执行的方法为圆心,最外层的order最小。从最外层按照AOP1、AOP2的顺序依次执行doAround方法,doBefore方法。然后执行method方法,最后按照AOP2、AOP1的顺序依次执行doAfter、doAfterReturn方法。也就是说对多个AOP来说,先before的,一定后after

    示例工程

    示例工程地址

  • 相关阅读:
    JavaScript.convertArray
    JavaScript.InjectedScriptHost
    linux基础之ssh
    linux基础之常见的文件查看命令
    linux基础之ls命令
    windows安装zabbix客户端及加入监控
    centons7编译安装zabbix3.4
    gitlab备份、还原及迁移
    gitlab在centons环境下的安装及使用
    Python操作sqlserver
  • 原文地址:https://www.cnblogs.com/chengxuxiaoyuan/p/12182500.html
Copyright © 2011-2022 走看看