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

3.spring-aop

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

3.spring-aop

Spring AOP 1. AOP简介:

AOP全称为Aspect Oriented Programming,表示面向切面编程

由此可以得出,切面是一种将那些与业务无关,但业务模块都需要使用的功能封装起来的技术。这样便于减少系统的重复代码,降低模块之间的耦合度。

2. AOP基本术语

连接点(Joinpoint)

连接点就是被拦截到的程序执行点,因为Spring只支持方法类型的连接点,所以在Spring中连接点就是被拦截到的方法。连接点由两个信息确定:

  • 方法( 表示程序执行点,即在哪个目标方法)
  • 相对点(表示方位,即目标方法的什么位置,比如调用前,后等)

切入点(Pointcut)

切入点是对连接点进行拦截的条件定义,切入点表达式如何和连接点匹配是AOP的核心,Spring缺省使用AspectJ切入点语法。 一般认为,所有的方法都可以认为是连接点,但是我们并不希望在所有的方法上都添加通知,而切入点的作用就是提供一组规则来匹配连接点,给满足规则的连接点添加通知。

通知、增强 (Advice)

可以为切入点添加额外功能,分为:前置通知、后置通知、异常通知、环绕通知等。

目标对象 (Target)

目标对象指将要被增强的对象,即包含主业务逻辑的类对象。或者说是被一个或者多个切面所通知的对象。

织入 (Weaving)

织入是将切面和业务逻辑对象连接起来, 并创建通知代理的过程。织入可以在编译时,类加载时和运行时完成。在编译时进行织入就是静态代理,而在运行时进行织入则是动态代理

代理 (Proxy)

被AOP织入通知后,产生的结果类。

切面 (Aspect)

切面是一个横切关注点的模块化,一个切面能够包含同一个类型的不同增强方法,比如说事务处理和日志处理可以理解为两个切面。切面由切入点和通知组成,它既包含了横切逻辑的定义,也包括了切入点的定义。 Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。

3. AOP应用

AOP应用场景有许多,最典型的应用场景就是日志和事务。

依赖:spring aop是依赖于spring ioc的,aop的通知类都需要放在spring的ioc容器中。


    org.springframework
    spring-context
    5.3.11

3.1 创建业务层

aop是针对业务层做的增强处理。

public interface UserService {
    int delete(String name);
}

public class UserServiceImpl implements UserService {
    @Override
    public int delete(String name) {
        System.out.println("这句话是执行删除业务");
//        int i=1/0;
        return 0;
    }
}
3.2. 配置业务层

AOP 功能的实现是基于 IOC 的,因此,业务层对象应该纳入 IOC 容器来管理。




    
    
    

3.3 创建通知类

aop中的通知分为五种:前置通知,后置通知,异常抛出通知,环绕通知,最终通知。

这些通知的执行顺序如下:

try {
  	//前置通知
    
    //---业务执行--------
    
    //后置通知
} catch (Throwable t){
    //异常抛出通知
} finally {
    //最终通知
}

前置通知类(实现MethodBeforeAdvice接口):

在业务层方法执行之前执行。

import org.springframework.aop.MethodBeforeAdvice;

public class BeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        //获取方法名
        String methodName = method.getName();
        //获取类名
        String className = method.getDeclaringClass().getName();
        System.out.println("这是前置通知:"+methodName+"----"+className+"参数:"+ Arrays.toString(args));
    }
}

后置通知类(实现AfterReturningAdvice接口):

在业务层方法执行结束后执行

import org.springframework.aop.AfterReturningAdvice;

public class AfterAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        //获取方法名
        String methodName = method.getName();
        //获取类名
        String className = method.getDeclaringClass().getName();
        System.out.println("这是后置通知:"+methodName+"----"+className+"参数:"+ Arrays.toString(args));
    }
}

异常抛出通知类(实现ThrowsAdvice接口):

在业务层执行方法抛出异常时执行。

import org.springframework.aop.ThrowsAdvice;

public class ExceptionAdvice implements ThrowsAdvice {
    
    public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
        String methodName = method.getName();
        String className = method.getDeclaringClass().getName();
        System.out.println("执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + ex.getMessage());
    }
}

最终通知类(实现AfterAdvice接口)

在业务层方法执行最终才执行,无论是否抛出异常。

注意:AfterAdvice是spring aop中的接口。

import org.springframework.aop.AfterAdvice;

public class FinallyAdvice implements AfterAdvice {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("最终通知");
    }
}

环绕通知类(实现MethodInterceptor接口):

包含前置、后置和异常通知和最终通知。

public class AroundAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod(); //获取被拦截的方法对象
        Object[] args = invocation.getArguments();//获取方法的参数
        Object target = invocation.getThis(); //获取代理对象
        String methodName = method.getName();
        String className = method.getDeclaringClass().getName();
        
        try {
            System.out.println("前置:准备执行方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args));
            //此处执行业务层的方法
            Object returnValue = method.invoke(target, args);
            
            System.out.println("后置:执行完方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",得到返回值:" + returnValue);
            //返回执行结果
            return returnValue;
        } catch (Throwable t){
            System.out.println("异常抛出:执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + t.getMessage());
            throw t;
        } finally {
            System.out.println("最终通知");
        }
    }
}
3.4 配置通知

这些通知类创建完成,还需要在xml配置文件中配置相关信息才能使用(装入ioc容器)




    

    
    
    
    
    
    
    
    
	
    
    
        
        
        
        
        
        

        
        
        

        
        
        
        
        
        
        
        
        
        
    

配置完成在调用service层方法时,就能够触发这些通知器。

3.5 测试
@Test
public void userDeleteTest(){
    //加载applicationContext.xml配置文件
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService = applicationContext.getBean("userService", UserService.class);

    userService.delete("dengshuo");
}

下一章介绍 aop的框架 AspectJ和java中的代理模式

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/425515.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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