• 12.21 Spring集成AspectJ


    12.21Spring集成AspectJ

    在新版本的Spring框架中使用AspectJ开发AOP

    AspectJ是什么

    概念:

    基于Java语言的AOP框架,扩展了Java语言

    使用AspectJ开发AOP的方式

    • 基于XML的声明式AspectJ

    • 基于Annotation的声明式AspectJ

    基于AspectJ XML开发Spring AOP

    具体是指:

    通过Spring配置文件的方式来定义切面、切入点、通知。

    具体实现:

    所有的切面和通知必须定义在<aop:config>元素中

    步骤:

    • 导入Spring aop命名空间

    • 定义切面

    • 定义切入点

    • 定义通知

    导入Spring aop命名空间
    <?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
      ...
    </beans>
    定义切面<aop:aspect>

    作用:

    把定义好的Bean转换成切面Bean。所以使用该元素需要先定义一个普通Spring Bean

    示例:

    <aop:config>
       <aop:aspect id="myAspect" ref="aBean">
          ...
       </aop:aspect>
    </aop:config>
    <!--
    id用来定义该切面唯一表示名称
    ref用于引用普通的Spring Bean
    -->
    定义切入点<aop:pointcut>

    作用:

    定义一个切入点

    • 作为<aop:config>元素的子元素---->表示该切入点是全局切入点

    • 作为<aop:aspect>元素的子元素--->表示该切入点只对当前切面有效

    示例:

    <aop:config>
       <aop:pointcut id="myPointCut"
           expression="execution(* com.junkingboy.service.*.*(..))"/>
    </aop:config>
    <!--
    id用于指定切入点的唯一标识名称
    execution指定切入点关联的切入点表达式
    -->

    execution格式:

    execution(modifiers-pattern returning-type-pattern declaring-type-pattern name-pattern(param-pattern)throws-pattern)
    • returning-type-pattern、name-pattern、param-pattern 是必须的,其它参数为可选项。

    • modifiers-pattern:指定修饰符,如 private、public。

    • returning-type-pattern:指定返回值类型,*表示可以为任何返回值。如果返回值为对象,则需指定全路径的类名。

    • declaring-type-pattern:指定方法的包名。

    • name-pattern:指定方法名,*代表所有,set* 代表以 set 开头的所有方法。

    • param-pattern:指定方法参数(声明的类型),(..)代表所有参数,(*)代表一个参数,(*,String)代表第一个参数可以为任何值,第二个为 String 类型的值。

    • throws-pattern:指定抛出的异常类型。

    定义通知

    具体可定义五种类型的advice

    <aop:aspect id="" ref="">
    <!-- 前置通知 -->
       <aop:before pointcut-ref="" method="" />
       
    <!-- 后置通知 -->
       <aop:after-returning pointcut-ref="" method="" />
    <!-- 环绕通知 -->
       <aop:around pointcut-ref="" method="" />
    <!-- 异常通知 -->
       <aop:after-throwing pointcut-ref="" method="" />
    <!-- 最终通知 -->
       <aop:after pointcut-ref="" method="" />
      ...
    </aop:aspect>

    理解:

    本质上就是通过xml对各个接口、类、Bean对象实现调用而非代码上的强制调用。

    定义loggin类:

    public class Logging {
       /**
        * 前置通知
        */
       public void beforeAdvice() {
           System.out.println("前置通知");
      }
       /**
        * 后置通知
        */
       public void afterAdvice() {
           System.out.println("后置通知");
      }
       /**
        * 返回后通知
        */
       public void afterReturningAdvice(Object retVal) {
           System.out.println("返回值为:" + retVal.toString());
      }
       /**
        * 抛出异常通知
        */
       public void afterThrowingAdvice(IllegalArgumentException ex) {
           System.out.println("这里的异常为:" + ex.toString());
      }
    }

    ORM的对象:

    package net.biancheng;
    public class Man {
       private String name;
       private int age;
       public String getName() {
           return name;
      }
       public void setName(String name) {
           this.name = name;
      }
       public int getAge() {
           return age;
      }
       public void setAge(int age) {
           this.age = age;
      }
       public void throwException() {
           System.out.println("抛出异常");
           throw new IllegalArgumentException();
      }
    }

    Beanxml

    <?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <!-- 使用config标签声明下面是配置 -->
       <aop:config>
      <aop:aspect id="log" ref="logging">
          <aop:pointcut id="selectAll" expression="excution()" />
          <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="" method="afterThrowingAdvice" />
           </aop:aspect>
           
           <!-- 下面定义bean -->
       <bean id="man" class="net.biancheng.Man">
           <property name="name" value="bianchengbang" />
           <property name="age" value="12" />
       </bean>
           
       <bean id="logging" class="net.biancheng.Logging" />
           
       </aop:config>

    启动类:

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class MainApp {
    public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
    Man man = (Man) context.getBean("man");
    man.getName();
    man.getAge();
    man.throwException();
    }
    }

    AspectJ基于注解开发AOP

    为了防止xml文件过于臃肿,AspectJ 框架为 AOP 开发提供了一套注解。AspectJ 允许使用注解定义切面、切入点和增强处理,Spring 框架可以根据这些注解生成 AOP 代理。

    Annotation注解介绍:

    名称说明
    @Aspect 用于定义一个切面。
    @Pointcut 用于定义一个切入点。
    @Before 用于定义前置通知,相当于 BeforeAdvice。
    @AfterReturning 用于定义后置通知,相当于 AfterReturningAdvice。
    @Around 用于定义环绕通知,相当于MethodInterceptor。
    @AfterThrowing 用于定义抛出通知,相当于ThrowAdvice。
    @After 用于定义最终final通知,不管是否异常,该通知都会执行。
    @DeclareParents 用于定义引介通知,相当于IntroductionInterceptor(不要求掌握)。

    @AspectJ注解的两种方法:

    使用@Configuration和@EnableAspectJAutoProxy注解:

    @Configuration
    @EnableAspectJAutoProxy
    public class Appconfig{

    }

    基于xml配置:

    <aop:aspectj-autoproxy>
    定义切面@Aspect

    使用Aspect注解:

    import org.aspectj.lang.annotation.Aspect;

    @Aspect
    public class AspectModule {
    }

    xml中配置:

    <bean id = "myAspect" class = "类路径">
    ...
    </bean>
    定义切入点@Pointcut

    使用Aspect注解*

    // 要求:方法必须是private,返回值类型为void,名称自定义,没有参数
    @Pointcut("execution(*包名..*.*(..))")
    private void myPointCut() {
    }

    xml中配置:

    <aop:pointcut expression="execution(*包名..*.*(..))"  id="myPointCut"/>
    定义通知advice

    上面说到的五种类型,以before作为示例:

    @Before("方法名")
    public void beforeAdvice(){
    ...
    }
    /* 表示在某个方法之后调用 */
  • 相关阅读:
    JVM系列一:虚拟机内存区域
    【转载】 mybatis入门系列四之动态SQL
    mybatis入门系列三之类型转换器
    mybatis入门系列二之输入与输出参数
    mybatis入门系列一之创建mybatis程序
    SpringBoot基础系列一
    如何阅读W3C标准.md
    wget下载豆瓣图片失败
    js中调用worker工程化结构
    linux下fastboot工具使用异常
  • 原文地址:https://www.cnblogs.com/JunkingBoy/p/15819327.html
Copyright © 2020-2023  润新知