栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring AOP

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring AOP

1.5 AOP 1.5.1 AOP概念

面向切面编程,在不修改源代码的情况下对方法进行增强(扩展)。

AOP底层使用动态代理实现

  1. 第一种情况,有接口情况,使用动态代理创建接口实现类代理对象
  2. 第二种情况,没有接口情况,使用动态代理创建类的子类代理对象
  • Joinpoint(连接点):类里面可以被增强的方法,这些方法称为连接点

  • Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义,例如:使用正则表达式

  • **Advice(通知/增强)*所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

  • Aspect(切面):是切入点和通知的结合

  • Introduction(引介):引介是一种特殊的通知,在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field(成员变量).

  • Target(目标对象):代理的目标对象(要增强的类)

  • Weaving(织入):是把增强应用到目标的过程。把advice 应用到 target的过程

  • Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

1.5.2 Spring AOP示例

在spring里面进行aop操作,需要导入aspectj的依赖

  1. aspectj不是spring 的一部分,和spring一起使用进行aop操作
  2. Spring 2.0后新增了对Aspectj支持

5种类型的通知

  • before:前置通知

    在方法执行前执行

  • afterReturning:后置通知

    方法正常返回后执行,如果方法中抛出异常,通知无法执行,必须在方法执行后才执行,可以获得方法的返回值

  • afterThrowing:抛出异常通知

    方法抛出异常后执行,如果方法没有抛出异常,无法执行

  • after:最终通知

    方法执行完毕后执行,无论方法中是否出现异常

  • around:环绕通知

    方法执行前后分别执行,可以阻止方法的执行,必须手动执行目标方法

项目导入maven依赖

 
     org.springframework
     spring-context
     5.2.12.RELEASE
	


    org.springframework
    spring-aspects
    5.2.9.RELEASE




	junit
	junit
	4.12
	test

基于配置文件实现

被增强的业务类

package com.jia;

public class UserService {
    public void task1(){
        System.out.println("task1");
    }
    public void task2(){
        System.out.println("task2");
    }
}

增强类

public class UserServiceAdvice {

    public void before1(){
        System.out.println("前置增强.........");
    }
    public void after1(){
        System.out.println("后置增强1.........");
    }
    public void after2(){
        System.out.println("后置增强2.........");
    }
    //环绕通知
    public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //方法之前
        System.out.println("方法之前.....");

        //执行被增强的方法
        proceedingJoinPoint.proceed();

        //方法之后
        System.out.println("方法之后.....");
    }
}

bean.xml配置

这里切入点匹配要被增强的方法时使用了正则表达式

execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>) 访问修饰符是可选的



    
    
    

    
    
        
        

        
        
            
            
            
            
            
        
    

测试

@Test
public  void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    UserService userService = context.getBean("userService", UserService.class);
    userService.task1();;
    System.out.println("---------------------------------");
    userService.task2();;
}

结果

前置增强.........
方法之前.....
task1
方法之后.....
后置增强2.........
后置增强1.........
---------------------------------
前置增强.........
方法之前.....
task2
方法之后.....
后置增强2.........
后置增强1.........

注意:该示例中配置了两个后置增强,最后结果显示先配置的后置增强后执行,这与底层aop实现中拦截器链的执行有关

基于注解实现

在spring核心配置文件中,开启aop操作



    
    
    
    
    
    

这里仍然使用第一种方法中的被增强类

在增强类上面使用注解完成aop操作

注意注解所在的包是 aspectj下的

@Aspect
public class ServiceAdvice {

    @Before(value = "execution(* com.jia.UserService.*)")
    public void before1(){
        System.out.println("前置增强.........");
    }
    @After(value = "execution(* com.jia.UserService.*)")
    public void after1(){
        System.out.println("后置增强1.........");
    }
    @After(value = "execution(* com.jia.UserService.*)")
    public void after2(){
        System.out.println("后置增强2.........");
    }
    
    @Around(value = "execution(* com.jia.UserService.*)")
    public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //方法之前
        System.out.println("方法之前.....");

        //执行被增强的方法
        proceedingJoinPoint.proceed();

        //方法之后
        System.out.println("方法之后.....");
    }
}

测试

@Test
public void test1(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    UserService userService = context.getBean("userService", UserService.class);
    userService.task1();
    System.out.println("---------------------------------");
    userService.task2();
}

结果

方法之前.....
前置增强.........
task1
后置增强2.........
后置增强1.........
方法之后.....
---------------------------------
方法之前.....
前置增强.........
task2
后置增强2.........
后置增强1.........
方法之后.....

ce.*)")
public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//方法之前
System.out.println(“方法之前…”);

    //执行被增强的方法
    proceedingJoinPoint.proceed();

    //方法之后
    System.out.println("方法之后.....");
}

}

测试

```java
@Test
public void test1(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    UserService userService = context.getBean("userService", UserService.class);
    userService.task1();
    System.out.println("---------------------------------");
    userService.task2();
}

结果

方法之前.....
前置增强.........
task1
后置增强2.........
后置增强1.........
方法之后.....
---------------------------------
方法之前.....
前置增强.........
task2
后置增强2.........
后置增强1.........
方法之后.....
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/284556.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号