JavaSpringAOP应用转载

原创
小哥 2年前 (2022-12-30) 阅读数 57 #大杂烩

Spring AOP

Java web 环境搭建
Java web 项目搭建
Java Spring IOC用法
spring提供两个核心功能,一个是IoC(控制反转)另一个是Aop(面向操作的编程),IoC有助于在对象之间应用解耦,AOP您可以将交叉关注点(如日志记录、安全性、缓存和事务管理)与其影响的对象分离。

1.简介

AOP它主要包括通知、切割点和连接点等术语,如下所述。

  • 通知(Advice)
    通知定义相切平面为 什么 以及 何时 调用,当调用包含以下内容时

    Before 调用方法之前调用通知
    After 方法完成后调用通知,无论方法执行是否成功
    After-returning 成功执行方法后调用通知
    After-throwing 方法引发异常后的调用通知
    Around 通知环绕通知的方法,在调用通知的方法之前和之后执行自定义行为

  • 切点(PointCut)
    通知定义了 什么何时 ,切点定义 何处 切点的定义将匹配要编织到通知中的一个或多个连接点,我们通常使用显式类的方法名来指定这些切点,或者使用正则表达式来定义匹配的类和方法名。
    切点的格式如下

    execution(* com.ganji.demo.service.user.UserService.GetDemoUser (..) )

  • 连接点(JoinPoint)
    连接点是在应用程序执行期间可以插入到切线平面中的点。这一点可以发生在调用方法、抛出异常或修改字段时。切平面代码可以使用这些连接点插入到应用程序的正常流中,并添加新的行为,如日志记录、安全性、事务、缓存等。

现阶段的AOP框架
AOP框架除了 Spring AOP 此外,它还包括 AspectJJBoss AOP
上述框架的区别在于Spring AOP只支持到方法连接点,其他两个也支持字段和构造函数连接点。

2.用法

与依赖注入类似,AOP在spring有两种配置方式,一种是。xml配置模式,第二种是自动注释模式。

  • 2.1 xml在中声明切平面

    • 2.1.1 AOP配置元素

    在xml在中,我们使用以下AOP配置元素声明方面

       AOP配置元素 | 描述 
      ------------ | -------------
      <aop:advisor> | 定义AOP通知器
      <aop:after>  | 定义AOP发布通知(无论方法是否成功执行)
      <aop:after-returning> | 成功执行方法后调用通知
      <aop:after-throwing> | 方法引发异常后的调用通知
      <aop:around> | 定义AOP环绕通知
      <aop:aspect> | 定义切面
      <aop:aspect-autoproxy> | 定义@AspectJ注释驱动切平面
      <aop:before> | 定义AOP前置通知
      <aop:config> | 顶层的AOP配置元素,大多数包含在元素内
      <aop:declare-parent> | 为通知对象引入其他接口并透明地实现它们
      <aop:pointcut> | 定义切点
    • 2.1.2 定义切面

    我们在service层添加 com.ganji.demo.service.aspect.XmlAopDemoUserLog 类,拦截方法在内部实现,如下所示

    package com.ganji.demo.service.aspect;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    /**
     * Created by admin on 2015/9/2.
     */
    public class XmlAopDemoUserLog {
    //    方法执行前的通知
        public void beforeLog() {
            System.out.println("开始预通知  日志记录");
        }
    //    方法执行后通知
        public void afterLog() {
            System.out.println("开始执行后通知 日志记录");
        }
    //    成功执行后的通知
        public void afterReturningLog() {
            System.out.println("成功执行方法后的通知 日志记录");
        }
    //    引发异常后的通知
        public void afterThrowingLog() {
            System.out.println("方法引发异常后执行通知 日志记录");
        }
    
    //    环绕通知
        public Object aroundLog(ProceedingJoinPoint joinpoint) {
            Object result = null;
            try {
                System.out.println("环绕通知开始 日志记录");
                long start = System.currentTimeMillis();
    
                //有返回参数 您需要返回一个值
                result =  joinpoint.proceed();
    
                long end = System.currentTimeMillis();
                System.out.println("总执行时间" + (end - start) + " 毫秒");
                System.out.println("环绕声结束通知 日志记录");
            } catch (Throwable t) {
                System.out.println("出现错误");
            }
            return result;
        }
    }
    • 2.1.3 xml声明方面并调用

    我们在web层, web-inf/dispatcher-servlet.xml 本节定义如下

    
    
    
         
            
            
            
            
            
            
            
        
    

    在controller呼叫,具体呼叫如下

    DemoUserEntity demoUser=userService.GetDemoUser(1);

    这快用完了 我们将看到打印出以下日志

    开始预通知 日志记录
    开始执行后通知 日志记录
    成功执行方法后的通知 日志记录

    • 2.1.4 小结

    如果通过xml配置,我们还可以实现环绕通知,其目的是共享通知前和通知后的信息。您还可以传递通知方法的参数。,在切线截距中验证了参数的有效性。

  • 2.2 自动注解AOP

    在上述2.1我们经过的地方xml配置的形式 实现了AOP编程,现在我们通过不配置xml,配置注释的表单实现。AOP。

    • 2.2.1 配置自动代理

    使用配置注释,首先我们将切片spring要自动代理的上下文bean我们需要进去web层的 web-inf/dispatcher-servlet.xml 可以在文件中配置以下语句

    <aop:aspectj-autoproxy />

    当然,我们需要xml的根目录beans下引用aop命名空间和xsi

    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
    • 2.2.2 使用 @Aspect 注解

    声明一个方面,只需将其添加到类名中。 @Aspect 属性,即特定的连接点,我们使用 @Pointcut@Before@After 具体如下
    在声明前 我们需要依靠配置pom

    
        org.aspectj
        aspectjrt
        1.6.11
    
    
        org.aspectj
        aspectjweaver
        1.6.11
    

    声明切线类,包括注释 @Aspect 以及何时(如 @Before )执行通知

    package com.ganji.demo.service.aspect;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Service;
    
    /**
     * Created by admin on 2015/9/2.
     */
    @Aspect
    @Service
    public class XmlAopDemoUserLog {
    
    // 配置切点 以及要传递的参数   
        @Pointcut("execution(* com.ganji.demo.service.user.UserService.GetDemoUser(..)) && args(id)")
        public void pointCut(int id)
        {
    
        }
    
    // 配置连接点 方法开始执行时通知
        @Before("pointCut(id)")
        public void beforeLog(int id) {
            System.out.println("开始预通知  日志记录:"+id);
        }
    //    方法执行后通知
        @After("pointCut(id)")
        public void afterLog(int id) {
            System.out.println("开始执行后通知 日志记录:"+id);
        }
    //    成功执行后的通知
        @AfterReturning("pointCut(id)")
        public void afterReturningLog(int id) {
            System.out.println("成功执行方法后的通知 日志记录:"+id);
        }
    //    引发异常后的通知
        @AfterThrowing("pointCut(id)")
        public void afterThrowingLog(int id) {
            System.out.println("方法引发异常后执行通知 日志记录"+id);
        }
    
    //    环绕通知
        @Around("pointCut(id)")
        public Object aroundLog(ProceedingJoinPoint joinpoint,int id) {
            Object result = null;
            try {
                System.out.println("环绕通知开始 日志记录"+id);
                long start = System.currentTimeMillis();
    
                //有返回参数 您需要返回一个值
                result =  joinpoint.proceed();
    
                long end = System.currentTimeMillis();
                System.out.println("总执行时间" + (end - start) + " 毫秒");
                System.out.println("环绕声结束通知 日志记录");
            } catch (Throwable t) {
                System.out.println("出现错误");
            }
            return result;
        }
    }
    • 2.2.3 总结

    遵循以上两个步骤并使用注释实现Aop也就是说,这取决于这里。IOC。

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门