• [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.


    [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

     

    前言: 
    在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习.

    一, AspectJ的概述:

    AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。

    Spring为了简化自身的AOP的开发,将AspectJ拿过来作为Spring自身一个AOP的开发.

    二, Spring AspectJ开发实例

    2.1 开发所需jar包



    2.2 AspectJ 注解开发规范

    2.2.1 @AspectJ提供不同的通知类型

    @Before 前置通知,相当于BeforeAdvice
      在执行目标方法之前完成一个操作,获得到切入点信息.

    @AfterReturning 后置通知,相当于AfterReturningAdvice

    1 在目标方法执行之后完成一个操作,获得方法的返回值.
    2 
    3 @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result")
    4 public void afterReturing(Object result){
    5     System.out.println("后置通知============"+result);
    6 }

    @Around 环绕通知,相当于MethodInterceptor

    复制代码
    1 在目标方法执行的前和执行后完成一个操作,阻止目标方法执行.
    2 
    3 @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))")
    4 public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    5     System.out.println("环绕前通知==========");
    6     Object obj = joinPoint.proceed();
    7     System.out.println("环绕后通知==========");
    8     return obj;
    9 }
    复制代码


    @AfterThrowing抛出通知,相当于ThrowAdvice

    1 在目标方法出现异常的时候,完成一个操作.获得异常信息.
    2 
    3 @AfterThrowing(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))",throwing="e")
    4 public void afterThrowing(Throwable e){
    5     System.out.println("异常抛出通知========="+e.getMessage());
    6 }

    @After 最终final通知,不管是否异常,该通知都会执行

    1 在目标方法任何情况下都会执行的操作.相当于finally中的代码.
    2 
    3 @After(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))")
    4 public void after(){
    5     System.out.println("最终通知===========");
    6 }


    2.2.2 通过配置启用@AspectJ切面

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xmlns:aop="http://www.springframework.org/schema/aop"
     5        xsi:schemaLocation="http://www.springframework.org/schema/beans
     6     http://www.springframework.org/schema/beans/spring-beans.xsd
     7     http://www.springframework.org/schema/aop
     8     http://www.springframework.org/schema/aop/spring-aop.xsd">
     9     <!-- 开启AspectJ自动代理-->    
    10     <aop:aspectj-autoproxy />
    11 </beans>
    复制代码

    2.2.3 在通知中通过value属性定义切点

    通过execution函数,可以定义切点的方法切入
    语法:
      execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
    例如
      匹配所有类public方法 execution(public * *(..))
      匹配指定包下所有类方法 execution(* cn.itcast.dao.*(..)) 不包含子包
      execution(* cn.itcast.dao..*(..)) ..*表示包、子孙包下所有类
      匹配指定类所有方法 execution(* cn.itcast.service.UserService.*(..))
      匹配实现特定接口所有类方法 execution(* cn.itcast.dao.GenericDAO+.*(..))
      匹配所有save开头的方法 execution(* save*(..))

    2.2.4 AspectJ的切入点:

    1 统一管理切入点的表达式.
    2 @Pointcut(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))")
    3 private void myPointcut1(){} //这个类没有实际用途, 只是为了@Pointcut 注解


    2.2.6 Aspect和Advisor的区别:

    Advisor :传统的切面.传统切面一般都是由一个切入点和一个通知的组合.
    Aspect :真正意义上的切面.由多个切入点和多个通知的组合.



    2.3 Spring AspctJ 基于注解模式的开发
    CustomerService.java:

    复制代码
    1 public interface CustomerService {
    2 
    3     public void save();
    4     public Integer update();
    5     public void delete();
    6     public void find();
    7 }
    复制代码

    CustomerServiceImpl.java:

    复制代码
     1 public class CustomerServiceImpl implements CustomerService {
     2 
     3     @Override
     4     public void save() {
     5         System.out.println("保存客户...");
     6     }
     7 
     8     @Override
     9     public Integer update() {
    10         System.out.println("修改客户...");
    11         return 100;
    12     }
    13 
    14     @Override
    15     public void delete() {
    16         System.out.println("删除客户...");
    17     }
    18 
    19     @Override
    20     public void find() {
    21         System.out.println("查询客户...");
    22         int d = 1 / 0;
    23     }
    24 
    25 }
    复制代码

    MyAspectAnno.java:

    复制代码
     1 /**
     2  * 自定义切面类:
     3  *
     4  */
     5 @Aspect
     6 public class MyAspectAnno {
     7 
     8     @Before(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.save(..))")
     9     public void before(JoinPoint joinPoint){
    10         System.out.println("前置通知============"+joinPoint);
    11     }
    12     
    13     @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result")
    14     public void afterReturing(Object result){
    15         System.out.println("后置通知============"+result);
    16     }
    17     
    18     @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))")
    19     public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    20         System.out.println("环绕前通知==========");
    21         Object obj = joinPoint.proceed();
    22         System.out.println("环绕后通知==========");
    23         return obj;
    24     }
    25     
    26     @AfterThrowing(value="MyAspectAnno.myPointcut1()",throwing="e")
    27     public void afterThrowing(Throwable e){
    28         System.out.println("异常抛出通知========="+e.getMessage());
    29     }
    30     
    31     @After(value="MyAspectAnno.myPointcut1()")
    32     public void after(){
    33         System.out.println("最终通知===========");
    34     }
    35     
    36     @Pointcut(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.find(..))")
    37     private void myPointcut1(){}
    38 }
    复制代码

    SpringDemo.java 测试类:

    复制代码
     1 @RunWith(SpringJUnit4ClassRunner.class)
     2 @ContextConfiguration("classpath:applicationContext.xml")
     3 public class SpringDemo1 {
     4 
     5     @Resource(name = "customerService")
     6     private CustomerService customerService;
     7 
     8     @Test
     9     public void demo1() {
    10         customerService.save();
    11         customerService.update();
    12         customerService.delete();
    13         customerService.find();
    14     }
    15 }
    复制代码


    applicationContext.xml 配置文件:

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xmlns:aop="http://www.springframework.org/schema/aop"
     5        xsi:schemaLocation="
     6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
     8     
     9     <!-- 使用注解完成AOP的开发 -->
    10     <aop:aspectj-autoproxy/>
    11     
    12     <!-- 目标对象 -->
    13     <bean id="customerService" class="cn.augmentum.aspectj.demo1.CustomerServiceImpl"/>
    14 
    15     <!-- 配置切面 -->
    16     <bean id="myAspectAnno" class="cn.augmentum.aspectj.demo1.MyAspectAnno"/>
    17 </beans>
    复制代码


    2.4 Spring AspctJ 基于xml模式的开发

    OrderService.java:

    复制代码
     1 public class OrderService {
     2     public void save(){
     3         System.out.println("保存订单...");
     4     }
     5     public Integer update(){
     6         System.out.println("修改订单...");
     7         return 200;
     8     }
     9     public void delete(){
    10         System.out.println("删除订单...");
    11     }
    12     public void find(){
    13         System.out.println("查询订单...");
    14         //int d = 1/ 0;
    15     }
    16 }
    复制代码

    MyAspectXml.java:

    复制代码
     1 public class MyAspectXml {
     2 
     3     public void before(){
     4         System.out.println("前置通知===========");
     5     }
     6     
     7     public void afterReturing(Object result){
     8         System.out.println("后置通知==========="+result);
     9     }
    10     
    11     public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    12         System.out.println("环绕前通知==========");
    13         Object obj = joinPoint.proceed();
    14         System.out.println("环绕后通知==========");
    15         return obj;
    16     }
    17     
    18     public void afterThrowing(Throwable e){
    19         System.out.println("异常抛出通知========"+e.getMessage());
    20     }
    21     
    22     public void after(){
    23         System.out.println("最终通知==========");
    24     }
    25 }
    复制代码

    SpringDemo.java 测试类:

    复制代码
     1 @RunWith(SpringJUnit4ClassRunner.class)
     2 @ContextConfiguration("classpath:applicationContext.xml")
     3 public class SpringDemo2 {
     4 
     5     @Resource(name="orderService")
     6     private OrderService orderService;
     7     
     8     @Test
     9     public void demo1(){
    10         orderService.save();
    11         orderService.update();
    12         orderService.delete();
    13         orderService.find();
    14     }
    15 }
    复制代码

    applicationContext.xml 配置文件:

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xmlns:aop="http://www.springframework.org/schema/aop"
     5        xsi:schemaLocation="
     6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
     8     
     9     <!-- 配置目标类 -->
    10     <bean id="orderService" class="cn.augmentum.aspectj.demo2.OrderService"></bean>
    11 
    12     <!-- 配置切面 -->
    13     <bean id="myAspectXml" class="cn.augmentum.aspectj.demo2.MyAspectXml"></bean>
    14 
    15     <!-- AOP的配置 -->
    16     <aop:config>
    17         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.save(..))" id="pointcut1"/>
    18         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.update(..))" id="pointcut2"/>
    19         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.delete(..))" id="pointcut3"/>
    20         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.find(..))" id="pointcut4"/>
    21         <aop:aspect ref="myAspectXml">
    22             <aop:before method="before" pointcut-ref="pointcut1"/>
    23             <aop:after-returning method="afterReturing" pointcut-ref="pointcut2" returning="result"/>
    24             <aop:around method="around" pointcut-ref="pointcut3"/>
    25             <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/>
    26             <aop:after method="after" pointcut-ref="pointcut4"/>
    27         </aop:aspect>
    28     </aop:config>
    29 </beans>
    复制代码
  • 相关阅读:
    python 字符串中的%s与format
    python中的virtualenv是干嘛的?
    grep 与 find 简单命令
    git merge 和 git rebase的区别
    git stash的用法
    git push的用法
    git pull与git fetch的区别
    辟谣平台 踩坑记(一)
    微信JS-SDK开发 入门指南
    linux 写U盘出现的问题
  • 原文地址:https://www.cnblogs.com/du-0210/p/8426715.html
Copyright © 2020-2023  润新知