• Spring AOP


    Spring AOP

    3.1 Spring AOP简介

    3.1.1 AOP

    Aspect-Oriented Programming,面向切面编程。是传统的OOP编程的一个重要的补充。OOP编程,只能子类继承父类的纵向重用。

    AOP采用的是横向抽取机制。将分散重复的代码抽离出来,在程序编译或者运行的过程,将代码用到需要的执行地方。

    3.1.2 AOP术语

    Aspect(切面)

    JoinPoint(连接点)

    Pointcut(切入点)

    Advice(通知增强处理)

    Target Object(目标对象)

    Proxy(代理)

    Weaving(织入)

    3.2 AspectJ开发

    基于XML配置

    1.UserDao.java

    package com.sty.dao;
    
    public interface UserDao {
    
        //添加用户
         void add();
    
        //删除用户
        void delete();
    }
    

    2.UserDaoImpl.java

    package com.sty.dao;
    
    public class UserDaoImpl implements UserDao {
        public void add() {
            System.out.println("增加一个用户");
        }
    
        public void delete() {
            System.out.println("删除一个用户");
        }
    }
    

    3.MyAspect.java

    package com.sty.dao.aspect;
    
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.springframework.lang.NonNull;
    
    
    /*
    * 面向切面类
    * */
    public class MyAspect {
        /*1.前置通知*/
        public void myBefore(@NonNull JoinPoint  joinPoint){
            System.out.println("前置通知:模拟执行权限。。。。。");
            System.out.println("目标类是:"+joinPoint.getTarget());
            System.out.println(","+"被植入增强处理的目标方法是"+joinPoint.getSignature().getName());
        }
    
        /*2.后置通知*/
        public void myAfterReturning(@NonNull JoinPoint joinPoint){
            System.out.println("后置通知:模拟记录日志");
            System.out.println("被植入增强处理的目标方法是"+joinPoint.getSignature().getName());
    
        }
        /*3.环绕通知
        * ProceedingJoinPoint 是JoinPoint子接口,表示可执行的目标方法
        * 1. 必须是Object返回值
        * 2. 参数必须是ProceedingJoinPoint类型
        * 3.必须throws Throwable
         *
        *
        * */
        public Object myAround(@NonNull  ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕开始:执行目标方法之前,模拟开启事务‘。。。。");
            //执行当前的方法
            Object proceed = proceedingJoinPoint.proceed();
    
            System.out.println("环绕结束:执行目标方法之后,模拟关闭事务‘。。。。");
            return proceed;
    
        }
        /*4.异常通知*/
        public void myAfterThrowing( JoinPoint joinPoint, @NonNull  Throwable throwable){
            System.out.println("异常通知:出错了"+ throwable.getMessage());
    
        }
    
    
        /*5.最终通知*/
     public  void myAfter(){
         System.out.println("模拟方法,释放资源");
     }
    
    }
    
    

    4.ApplicationContext.xml

    <?xml version="1.0" encoding="UTF8"?>
             <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:context="http://www.springframework.org/schema/context"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xmlns:util="http://www.springframework.org/schema/util"
                    xmlns="http://www.springframework.org/schema/beans"
                    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/aop
                  http://www.springframework.org/schema/aop/spring-aop.xsd">
         <!--1.目标类-->
      <bean id="userDao" class="com.sty.dao.UserDaoImpl"/>
    
    
       <!--2.切面-->
    <bean id="myAspect" class="com.sty.dao.aspect.MyAspect"/>
    
       <!--3.Aop编程-->
       <aop:config>
          <!--3.1配置切面-->
          <aop:aspect id="aspect" ref="myAspect">
          <!--3.2配置切点-->
           <aop:pointcut id="myPointCut" expression="execution(* com.sty.dao.UserDaoImpl.add(..))"/>
             <!--3.3配置通知-->
            <aop:before method="myBefore" pointcut-ref="myPointCut"/>
             <aop:around method="myAround" pointcut-ref="myPointCut"/>
             <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="returnVal"/>
             <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="throwable"/>
             <aop:after method="myAfter" pointcut-ref="myPointCut"/>
          </aop:aspect>
       </aop:config>
    
    
    
    </beans>
    

    5.测试

    public class MyTest2 {
        /*自定义切面*/
        @Test
        public void TestDiy() {
            ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    
               UserDao userDao = (UserDao) context.getBean("userDao");
                userDao.add();
            System.out.println("------------------");
                userDao.delete();
    

    注解配置

    1.UserDao

    package com.sty.AnnotationDao;
    import org.springframework.stereotype.Repository;
    public interface UserDao {
    
        //添加用户
         void add();
    
        //删除用户
        void delete();
    }
    
    

    2.UserDaoImpl.java

    package com.sty.AnnotationDao;
    
    import org.springframework.stereotype.Repository;
    
    @Repository("userDao")
    public class UserDaoImpl implements UserDao {
        public void add() {
            System.out.println("增加一个用户");
        }
    
        public void delete() {
            System.out.println("删除一个用户");
        }
    }
    
    

    3.myAspect.java

    package com.sty.AnnotationDao.aspect;
    
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.lang.NonNull;
    import org.springframework.stereotype.Component;
    
    
    /*
    * 面向切面类
    * */
    @Component
    @Aspect //定义一个切面
    public class MyAspect {
    
        /*定义一个表达式*/
        @Pointcut("execution(* com.sty.AnnotationDao.*.*(..))")
        public void myPointCut(){}
    
    
        /*1.前置通知*/
        @Before("myPointCut()")
        public void myBefore(@NonNull JoinPoint  joinPoint){
            System.out.println("前置通知:模拟执行权限。。。。。");
            System.out.println("目标类是:"+joinPoint.getTarget());
            System.out.println(","+"被植入增强处理的目标方法是"+joinPoint.getSignature().getName());
        }
    
        /*2.后置通知*/
        @After("myPointCut()")
        public void myAfterReturning(@NonNull JoinPoint joinPoint){
            System.out.println("后置通知:模拟记录日志");
            System.out.println("被植入增强处理的目标方法是"+joinPoint.getSignature().getName());
    
        }
        /*3.环绕通知
        * ProceedingJoinPoint 是JoinPoint子接口,表示可执行的目标方法
        * 1. 必须是Object返回值
        * 2. 参数必须是ProceedingJoinPoint类型
        * 3.必须throws Throwable
         *
        *
        * */
        @Around("myPointCut()")
        public Object myAround(@NonNull  ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕开始:执行目标方法之前,模拟开启事务‘。。。。");
            //执行当前的方法
    
            Object proceed = proceedingJoinPoint.proceed();
    
            System.out.println("环绕结束:执行目标方法之后,模拟关闭事务‘。。。。");
            return proceed;
    
        }
        /*4.异常通知*/
        @AfterThrowing(value = "myPointCut()",throwing = "throwable")
        public void myAfterThrowing( JoinPoint joinPoint, @NonNull  Throwable throwable){
            System.out.println("异常通知:出错了"+ throwable.getMessage());
    
        }
    
    
        /*5.最终通知*/
        @After("myPointCut()")
     public  void myAfter(){
         System.out.println("模拟方法,释放资源");
     }
    
    }
    
    

    4.application.xml

    <?xml version="1.0" encoding="UTF8"?>
             <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:context="http://www.springframework.org/schema/context"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xmlns:util="http://www.springframework.org/schema/util"
                    xmlns="http://www.springframework.org/schema/beans"
                    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/aop
                  http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    
    
    
    
    
        <!--指定需要扫描的包-->
        <context:component-scan base-package="com.sty"/>
    
        <!--启动基于注解的声名式Aspect支持-->
        <aop:aspectj-autoproxy/>
    
    </beans>
    
  • 相关阅读:
    pdf工具类之合并pdf文件
    Java 处理不可见特殊字符的坑
    将本地的jar包加到maven中,pom添加依赖
    SQLServer常用个技巧(一):根据某字符截取后面的字符串,String转int
    java下载文件写的工具类
    使用SWFTools将pdf转成swf
    使用openOffice将office文件转成pdf
    poi处理excel基本操作时写的工具类
    poi处理excel的合并单元格写的工具类,支持xlsx和xls
    java有关正则表达式的工具方法集合1
  • 原文地址:https://www.cnblogs.com/stydejava/p/14067487.html
Copyright © 2020-2023  润新知