`
collegeyuan
  • 浏览: 31475 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

基于注解spring AOP ,简单实现

 
阅读更多

        AspectJ允许使用注解定义切面、切入点和增强处理,而spring框架则可识别并根据这些注解来生成AOP的代理。spring只是使用了和AspectJ5一样的注解。但并没有使用AspectJ的编译器或织入器(编译时增强.class文件),底层依然使用spring AOP的动态代理。(运行时生成代理增加类,代理类=增强处理+目标对象方法)

 

一、简单的spring AOP实现实例

            前期准备:

                将jar包:aspectjweaver.jar、aspectjrt.jar 、aopalliance.jar放入lib目录下

 

            1)、定义普通bean、切面类 。切面类中定义@Before的增强处理

                包路径:com.spring.aspect.log.LogAspect.java

                      @Aspect

                     public class LogAspect {

 

                               //将com.spring.test1包下的所有类的所有方法,织入Before增强通知

                             @Before("execution(* com.spring.test1.*.*(..))")

                             public void log(){

 

                                           System.out.println("打日志");

                                }

                         }

 

                      com.spring.test1下有以下两个bean:Person、Axe,这两个bean将被织入前置通知

                             @Component

                             public class Person {

 

                                          @Autowired

                                          public Axe axe;

 

                                          public void printAxe(){

 

                                                        System.out.println(axe.chop());

                                             }

                                 }

 

                        @Component

                         public class Axe {

 

                                    public String chop(){

 

                                            return "这是axe方法";

                                     }

                             }

            2)、 在spring配置文件中,spring-config.xml下增加如下配置:

 

                       <!-- 扫描bean组件 -->

                      <context:annotation-config />

                      <!-- 启动@AspectJ支持 -->

                      <aop:aspectj-autoproxy/>

                     <!-- 添加bean组件、切面的扫描包 -->

                     <context:component-scan base-package="com.spring.test1,com.spring.aspect.log">

                     <context:include-filter type="annotation"

                                    expression="org.aspectj.lang.annotation.Aspect"/>

                     </context:component-scan>

 

 

        执行main方法:

 

           public class GetSpringBeanByxml {

 

             /**

              * @param args

             */

             public static void main(String[] args) throws Exception{

              // TODO Auto-generated method stub

 

                        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");

     

                        Person person  =ctx.getBean("person",Person.class);

 

                        person.printAxe();

                  }

 

              }

                  运行结果如下:

 

                          打日志

                          打日志

                          这是axe方法

 

 

 

-------------------------------------------------------------------------------------------------------------------------

二、定义切入点

       定义切入点实质就是为切入点起一个名称。可以在多个增强处理方法上重复使用该名称。

       切入点采用一个普遍的方法(方法体通常为空)来定义,切入点方法的返回值必须为void,并且用@PointCut来注释。如下:(修改一 中的logAspect()方法)

 

    @Aspect

     public class LogAspect {

 

        //定义切入点

        @PointCut("execution(* com.spring.test1.*.*(..))")

          public  void addLog(){}

 

         //使用切入点

          @Before(pointcut="addLog()")

           public void log(){

 

                      System.out.println("打日志");

            }

      }

一旦程序定义了切入点后,程序就可以重复使用该切入点,甚至可以在其它切面类、其它包的切面类中使用该切入点,至于能否在其它切面类、其它包切面类中使用该切入点,取决于改切入点方法前的访问控制符。例如上面addlog()方法的访问控制符为public,则意味可以在任何其它切面类中访问该切入点,如果为private,则只能在改切面中使用该切入点。

 在其它切面类中使用该切入点方法如下:

        @Aspect

     public class TransAspect {

 

         //使用切入点

          @Before(pointcut="LogAspect.addLog()")

           public void log(){

 

                      System.out.println("打日志");

            }

      }

 

-----------------------------------------------------------------------------------------------------------------------------

三、AOP增强处理注解:

  @After("execution(* org......*.*(..))") 增强处理不管目标方法如何结束(包括正常结束和异常结束)都织入

  @AfterReturning(returning="rvt“, "execution(* org......*.*(..))")只有目标方法正常结束才被织入 returning是只目标方法的返回类型。rvt为object,只有目标方法为object类型,才会被织入。Object rvt可做于增强处理方法的形参。来获取目标方法的返回值。

   @AfterThrowing(throwing="ex" ,"execution(* org......*.*(..))")处理目前方法抛异常的情况。throwing=NullPointer-Exception,则只处理nullPointException异常的方法

    @Around

            @Around可以决定目标方法什么时候执行,如何执行,甚至阻止目标方法的执行。改变目标方法的返回值。但通常需要在线程安全的情况下使用。@Around增强处理方法的第一个形参必须是ProceedingJoinPoint类型,调用ProceedingJoinPoint的proceed()方法,目标方法才会被执行,否则目标方法不会被执行。proceed()方法有一个参数object[]数组,该数组的值被传入目标方法作为目标方法的实参。

            例:

     @Aspect

     public class TxAspect{

            @Around("execution(* com.spring.test1.*.*(..))")

            public Object  processTx(ProceedingJoinPoint jp){

                System.out.println("执行目标方法开始之前,模拟开始事务。。。。”)

                //获取目标方法的原始参数

                  Object[]  args=jp.getArgs();

                   if(args!=null &&args.length>1){

                         //修改目标参数第一参数的值

                          arg[0] = “增强的前缀”+arg[0];

                    }

                  //以改变后的参数取执行目标方法,并保存目标方法的返回值

                  Object rvt = jp.proceed(args);

                   System.out.println("执行目标方法开始之前,模拟结束事务。。。。”)

                 if(rvt != null && rvt instanceOf Integer)

                         rvt = (Integer)rvt* (Integer)rvt;

                   return rvt;

       }

   

 

------------------------------------------------------

四、访问目标方法的参数:

  修改如下方法,使其访问目标方法的参数:

 

 @Aspect

     public class LogAspect {

 

          @Before("execution(* com.spring.test1.*.*(..))")

           public void log(){

 

                      System.out.println("打日志");

            }

 

      }

  第一种方式:修改为:

         @Aspect

     public class LogAspect {

 

          @Before("execution(* com.spring.test1.*.*(..))")

           public void log(JoinPoint jp){

 

                      System.out.println("打日志");

                      System.out.println(“被织入增强处理的目标方法为:” + jp.getSignature().getName());

                      System.out.println(“被织入增强处理的目标方法参数为:” + jp.getArgs());

            }

      }

 

 第二种方式,修改为:

 

     @Aspect

     public class LogAspect {

 

          @Before("execution(* com.spring.test1.*.*(..))  && args(arg0,arg1)")

           public void log(String arg0,String  arg1){

 

                      System.out.println("打日志");

                      System.out.println(“目标方法第一个参数为:” + arg0);

                      System.out.println(“目标方法第二个参数为:” + arg1);

            }

      }

   第二种方式,在切入点加&& args(arg0,arg1)部分,意味可以在增强处理方法中指定两个形参,定义这两个形参时,类型可以随意指定,一旦指定了类型,则会限制目标方法。例如此处指定了两个string类型的参数,这就意味着目前方法必须带有两个string类型的参数。

 

--------------------------------------

五、增强处理的织入顺序

          在不同的切面里两个增强处理需要在同一连接点被织入时,spring AOP将随机的顺序来织入这两个增强处理。如果指定不同切面的增强处理的优先级,有如下两种方式:

   1)让切面类实现org.springframework.core.Ordered接口。实现改接口的intgetOrder()方法。改方法返回值越小优先级越高。

   2)直接使用@Order注解来修改切面类。使用@order注解时指定一个int型的value属性。改属性值越小,优先级越高。

 

 

 

      

 

分享到:
评论

相关推荐

    基于注解实现SpringAop

    基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop

    Spring基于注解实现AOP

    本篇文章将深入探讨如何在Spring中通过注解实现AOP。 首先,了解AOP的基本概念。面向切面编程是一种编程范式,它允许程序员定义“切面”,这些切面包含了跨越多个对象的行为或责任。切点是这些行为插入到主业务逻辑...

    Spring Aop的简单实现

    在这个基于配置文件的实现中,我们首先需要在Spring配置文件(如applicationContext.xml)中定义一个切面。切面通常由一个或多个通知组成,我们可以使用`&lt;aop:config&gt;`标签来声明切面。例如: ```xml &lt;aop:config&gt; ...

    Spring AOP实现机制

    **Spring AOP 实现机制详解** Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许程序员在不修改源代码的情况下,通过“切面”来插入额外的业务逻辑,如日志、事务管理等。AOP的引入极大地提高了代码的...

    使用Spring的注解方式实现AOP的细节

    5. **@EnableAspectJAutoProxy**: 在Spring配置类上添加此注解,启用基于Java代理的AOP支持,这样Spring会自动检测并处理带有@Aspect注解的类。 ```java @Configuration @EnableAspectJAutoProxy public class ...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、可在现有源码上快速进行功能扩展 4、spring boot,mybatis,druid,spring aop的使用

    Spring AOP的简单实现

    在这个场景中,我们将使用Spring AOP来实现一个日志记录的功能,以追踪系统中各个方法的调用情况,包括访问时间以及传递的参数。下面将详细阐述如何实现这一目标。 首先,我们需要了解AOP的基本概念。AOP的核心是切...

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    在Spring AOP中,我们通常使用@Aspect注解来定义切面类。切面类中可以包含多个通知(Advice),包括前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知...

    Spring 基于注解方式实现AOP

    在Spring框架中,基于注解的AOP(面向切面编程)是一种强大的工具,它允许开发者无需编写XML配置即可实现切面。这种编程方式极大地提高了代码的可读性和可维护性。下面我们将深入探讨如何使用注解来实现Spring AOP。...

    spring aop jar 包

    这个"spring aop jar 包"包含了实现这一功能所需的类和接口,使得开发者能够轻松地实现面向切面的编程。 在Spring AOP中,主要涉及以下几个核心概念: 1. **切面(Aspect)**:切面是关注点的模块化,比如日志记录...

    SpringAop学习笔记以及实现Demo

    2. **基于注解的AOP**:Spring 2.5开始支持注解驱动的AOP,通过在方法上使用`@Before`、`@After`、`@AfterReturning`、`@AfterThrowing`、`@Around`等注解来定义通知。 3. **基于XML配置的AOP**:在Spring的配置...

    Spring AOP 的实现例子(基于XML配置实现)

    XML配置是Spring AOP早期的主要实现方式,虽然现在有更简洁的注解式配置,但理解XML配置方式对于深入理解AOP原理仍然很有帮助。下面我们将详细探讨如何通过XML配置实现Spring AOP。 首先,我们需要在Spring配置文件...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    Spring AOP在内部也是基于类似的方式工作,但它的实现更为复杂和高效。它不仅可以处理接口代理,还可以处理基于类的代理,支持CGLIB库生成字节码实现。此外,Spring AOP还提供了一套强大的切点表达式和注解,使得...

    Spring AOP 16道面试题及答案.docx

    Spring支持两种AOP的实现方式:Spring AspectJ注解风格和Spring XML配置风格。使用AspectJ注解风格是最常见的,它允许开发者直接在方法上使用注解来定义切面。 Spring AOP中有五种不同类型的的通知(Advice): 1....

    springboot spring aop 拦截器注解方式实现脱敏

    总结一下,通过上述步骤,我们已经在Spring Boot应用中利用Spring AOP和注解方式实现了数据脱敏。这个拦截器可以在不修改原有业务代码的情况下,确保敏感信息在响应给客户端之前得到处理,提高了应用的安全性。同时...

    一个简单的spring AOP的实现

    1. 注解驱动的AOP:这是最常用的实现方式,通过在方法上添加注解(如`@Before`, `@After`, `@Around`, `@AfterReturning`, `@AfterThrowing`)来定义通知,并使用`@Aspect`注解定义切面。 2. XML配置驱动的AOP:...

    注解方式实现AOP编程

    在Spring框架中,AOP的实现有两种主要方式:一种是基于XML配置,另一种是基于注解。本篇将主要讨论如何通过注解方式来实现AOP编程。 首先,我们需要了解Spring中的核心注解。`@Aspect`是定义一个切面的注解,通常会...

    Spring Aop四个依赖的Jar包

    Spring AOP就是基于这些接口进行设计的,因此这个库是Spring AOP和其他AOP实现之间协作的基础。 在实际使用中,我们需要在项目的类路径下包含这些Jar包,并在Spring配置文件中启用AOP支持。例如,可以通过以下XML...

    spring aop注解版

    在本主题中,我们将深入探讨Spring AOP的注解版,它是基于Java注解的实现,简化了配置并提高了代码的可读性。 首先,让我们理解AOP的基本概念。AOP是一种编程范式,允许程序员定义“切面”,这些切面封装了跨越多个...

    SpringAOP简单项目实现

    总结,这个"SpringAOP简单项目实现"涵盖了Spring AOP的基础知识,包括切面、通知、切入点的定义与配置,以及如何在实际项目中使用Maven进行构建和依赖管理。对于初学者来说,这是一个很好的实践案例,能够帮助他们...

Global site tag (gtag.js) - Google Analytics