zoukankan      html  css  js  c++  java
  • Spring 中基于 AOP 的 @AspectJ

    Spring 中基于 AOP 的 @AspectJ

    @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格。

    通过在你的基于架构的 XML 配置文件中包含以下元素,@AspectJ 支持是可用的。

    <aop:aspectj-autoproxy/>
    

    声明一个 aspect

    Aspects 类和其他任何正常的 bean 一样,除了它们将会用 @AspectJ 注释之外,它和其他类一样可能有方法和字段,如下所示:

    package org.xyz;
    import org.aspectj.lang.annotation.Aspect;
    @Aspect
    public class AspectModule {
    }
    

    它们将在 XML 中按照如下进行配置,就和其他任何 bean 一样:

    <bean id="myAspect" class="org.xyz.AspectModule">
       <!-- configure properties of aspect here as normal -->
    </bean>
    

    声明一个切入点

    一个切入点有助于确定使用不同建议执行的感兴趣的连接点(即方法)。在处理基于配置的 XML 架构时,切入点的声明有两个部分:

    • 一个切入点表达式决定了我们感兴趣的哪个方法会真正被执行。

    • 一个切入点标签包含一个名称和任意数量的参数。方法的真正内容是不相干的,并且实际上它应该是空的。

    下面的示例中定义了一个名为 ‘businessService’ 的切入点,该切入点将与 com.xyz.myapp.service 包下的类中可用的每一个方法相匹配:

    import org.aspectj.lang.annotation.Pointcut;
    @Pointcut("execution(* com.xyz.myapp.service.*.*(..))") // expression 
    private void businessService() {}  // signature
    

    下面的示例中定义了一个名为 ‘getname’ 的切入点,该切入点将与 com.tutorialspoint 包下的 Student 类中的 getName() 方法相匹配:

    import org.aspectj.lang.annotation.Pointcut;
    @Pointcut("execution(* com.tutorialspoint.Student.getName(..))") 
    private void getname() {}
    

    声明建议

    你可以使用 @{ADVICE-NAME} 注释声明五个建议中的任意一个,如下所示。这假设你已经定义了一个切入点标签方法 businessService():

    @Before("businessService()")
    public void doBeforeTask(){
     ...
    }
    @After("businessService()")
    public void doAfterTask(){
     ...
    }
    @AfterReturning(pointcut = "businessService()", returning="retVal")
    public void doAfterReturnningTask(Object retVal){
      // you can intercept retVal here.
      ...
    }
    @AfterThrowing(pointcut = "businessService()", throwing="ex")
    public void doAfterThrowingTask(Exception ex){
      // you can intercept thrown exception here.
      ...
    }
    @Around("businessService()")
    public void doAroundTask(){
     ...
    }
    

    基于 AOP 的 @AspectJ 示例

    • 新建Spring项目

    • 在项目中添加 Spring AOP 指定的库文件 aspectjrt.jar, aspectjweaver.jar 和 aspectj.jar。

    • 保证aspectjweaver.jar的版本在1.8以上,否则会报错。

    • 创建 Java 类 Logging, Student 和 MainApp

    这里是 Logging.java 文件的内容。这实际上是 aspect 模块的一个示例,它定义了在各个点调用的方法。

    package hello;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Around;
    
    //import org.springframework.aop.aspectj.AspectJAfterThrowingAdvice;
    @Aspect
    public class Logging {
        /** Following is the definition for a pointcut to select
         *  all the methods available. So advice will be called
         *  for all the methods.
         */
        @Pointcut("execution(* hello.*.*(..))")
        private void selectAll(){}
        /**
         * This is the method which I would like to execute
         * before a selected method execution.
         */
        @Before("selectAll()")
        public void beforeAdvice(){
            System.out.println("Going to setup student profile.");
        }
        /**
         * This is the method which I would like to execute
         * after a selected method execution.
         */
        @After("selectAll()")
        public void afterAdvice(){
            System.out.println("Student profile has been setup");
        }
        /**
         * This is the method which I would like to execute
         * when any method returns.
         */
        @AfterReturning(pointcut = "selectAll()", returning = "retVal")
        public void afterReturningAdvice(Object retVal){
            System.out.println("Returning:"+retVal.toString());
        }
        /**
         * This is the method which I would like to execute
         * if there is an exception raised.
         */
        @AfterThrowing(pointcut = "selectAll()", throwing = "ex")
        public void AfterThrowingAdvice(IllegalArgumentException ex){
            System.out.println("there has been an exception:"+ex.toString());
        }
    }
    

    下面是 Student.java 文件的内容:

    package hello;
    //import org.springframework.beans.factory.annotation.Autowired;
    
    public class Student {
        private int age;
        private String name;
        public void setAge(int age){
            this.age = age;
        }
        public int getAge(){
            System.out.println("age:"+age);
            return age;
        }
        public void setName(String name){
            this.name = name;
        }
        public String getName(){
            System.out.println("name:"+name);
            return name;
        }
        public void printThrowException(){
            System.out.println("Exception raised");
            throw new IllegalArgumentException();
        }
    }
    

    下面是 MainApp.java 文件的内容:

    package hello;
    //import org.springframework.context.support.AbstractApplicationContext;
    //import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    //import org.springframework.context.annotation.*;
    
    public class MainApp {
        public static void main(String[] args) {
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("Beans.xml");
            Student student = (Student) context.getBean("student");
            student.getName();
            student.getAge();
            //student.printThrowException();
        }
    }
    

    下面是配置文件 Beans.xml:

    <?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">
    
        <!--aop:config>
            <aop:aspect id="log" ref="logging">
                <aop:pointcut id="selectAll" expression="execution(* hello.*.*(..))"/>
                <aop:before pointcut-ref="selectAll" method="beforeAdvice"/>
                <aop:after pointcut-ref="selectAll" method="afterAdvice"/>
                <aop:after-returning pointcut-ref="selectAll"
                                     returning="retVal"
                                     method="afterReturningAdvice"/>
                <aop:after-throwing pointcut-ref="selectAll"
                                    throwing="ex"
                                    method="AfterThrowingAdvice"/>
            </aop:aspect>
        </aop:config-->
    
        <aop:aspectj-autoproxy/>
    
        <!-- Definition for student bean -->
        <bean id="student" class="hello.Student">
            <property name="name" value="番茄"/>
            <property name="age" value="10"/>
        </bean>
    
        <!-- Definition for logging aspect -->
        <bean id="logging" class="hello.Logging">
        </bean>
    
    </beans>
    

    运行一下应用程序

    Going to setup student profile.
    name:番茄
    Student profile has been setup
    Returning:番茄
    Going to setup student profile.
    age:10
    Student profile has been setup
    Returning:10
    
    Process finished with exit code 0
    

    每天学习一点点,每天进步一点点。

  • 相关阅读:
    C# 中 KeyPress 、KeyDown 和KeyUp的区别(转载)
    DataBinding的大用
    C#中的非托管资源释放(Finalize&Dispose)(转载)
    如何实现控件从IDE拖放到窗体上的效果?
    怎么在DataGridView中动态添加DateTimePicker列?
    电子表格(SpreadSheet)主要属性、方法和事件 原文:http://blog.csdn.net/zhangting1987/article/details/2065871
    C#利用KeyValuePair实现Dictionary的遍历方法
    Winform 打印报表
    vs2008 此安装不支持该项目类型
    WinForm里面使用多线程修改主线程上的一个Label的值
  • 原文地址:https://www.cnblogs.com/youcoding/p/12812926.html
Copyright © 2011-2022 走看看