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

Spring应用之AOP

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

Spring应用之AOP

1. SpringAOP介绍

AOP即面向切面编程,切面泛指系统中与主业务无关的代码,比如安全检查、日志记录、事物等等。AOP可以让主业务逻辑代码与切面代码分别开发,在运行时再进行合并。AOP减少了代码的纠缠,使业务逻辑代码更加清晰。

术语说明
切面切面泛指交叉业务逻辑。比如事务处理、日志处理就可以理解为切面。常用的切面有通知与顾问。实际就是对主业务逻辑的一种增强
织入织入是指将切面代码插入到目标对象的过程。
连接点连接点指切面可以织入的位置。
切入点切入点指切面具体织入的位置。
通知(Advice)通知是切面的一种实现,可以完成简单织入功能(织入功能就是在这里完成的)。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。
顾问(Advisor)顾问是切面的另一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将通知包装为更复杂切面的装配器。 不仅指定了切入时间点,还可以指定具体的切入点
2. 基于XML方式实现 2.1. 添加依赖
    
        
        
            org.springframework
            spring-context
            5.1.17.RELEASE
        
        
        
            org.springframework
            spring-aspects
            4.3.12.RELEASE
        
        
        
            junit
            junit
            4.12
            test
        
    
2.2. 创建切面类

创建切面类实现不同时机的通知方法

package com.wxw.aspectj;

public class AspectJBean {

    public void before(){
        System.out.println("AspectJBean前置通知!!!");
    }

    public void afterReturning(){
        System.out.println("AspectJBean后置通知!!!");
    }

    public void afterThrowing(){
        System.out.println("AspectJBean异常通知!!!");
    }

    public void after(){
        System.out.println("AspectJBean最终通知!!!");
    }

}
2.3. 创建目标类
package com.wxw.controller;

public class UserController {

    public void queryUser(){
        System.out.println("【UserController】的【queryUser】方法执行了!!!");
    }

}
2.4. 配置文件



    

    

    
        
        
        
        
            
            
            
            
            
        
    

2.5. 运行测试
package com.wxw.test;

import com.wxw.controller.UserController;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDemo {

    @Test
    public void test01(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = applicationContext.getBean("userController", UserController.class);
        userController.queryUser();
    }

}

AspectJBean前置通知!!!
【UserController】的【queryUser】方法执行了!!!
AspectJBean后置通知!!!
AspectJBean最终通知!!!

进程已结束,退出代码为 0
3. 基于注解方式实现 3.1. 添加依赖
    
        
        
            org.springframework
            spring-context
            5.1.17.RELEASE
        
        
        
            org.springframework
            spring-aspects
            4.3.12.RELEASE
        
        
        
            junit
            junit
            4.12
            test
        
    
3.2. 创建切面类

创建切面类实现不同时机的通知方法

package com.wxw.aspectj;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect // 显示的表明当前类是一个切面类
@Component  // 将该对象加载到IoC容器中
public class AspectJBean {

    @Before("execution(* com.wxw.controller.UserController.*(..))")
    public void before(){
        System.out.println("AspectJBean前置通知!!!");
    }

    @AfterReturning("execution(* com.wxw.controller.UserController.*(..))")
    public void afterReturning(){
        System.out.println("AspectJBean后置通知!!!");
    }

    @AfterThrowing("execution(* com.wxw.controller.UserController.*(..))")
    public void afterThrowing(){
        System.out.println("AspectJBean异常通知!!!");
    }

    @After("execution(* com.wxw.controller.UserController.*(..))")
    public void after(){
        System.out.println("AspectJBean最终通知!!!");
    }

}
3.3. 创建目标类
package com.wxw.controller;

import org.springframework.stereotype.Controller;

@Controller
public class UserController {

    public void queryUser(){
        System.out.println("【UserController】的【queryUser】方法执行了!!!");
    }

}
3.4. 运行测试
package com.wxw;

import com.wxw.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class JavaConfig {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
        UserController bean = applicationContext.getBean(UserController.class);
        bean.queryUser();
    }

}
AspectJBean前置通知!!!
【UserController】的【queryUser】方法执行了!!!
AspectJBean最终通知!!!
AspectJBean后置通知!!!

进程已结束,退出代码为 0
4. 切入点表达式
表达式类型说明
execution定位到目标对象的方法上
within定位到具体的类型上
this代理对象的类型
target目标对象的类型
args参数的类型
@args传入的参数有被该注解修饰
@within类型修饰的注解
@annotation方法修饰的注解

execution表达式语法: execution([访问权限类型] 返回值类型 [全限定类名] 方法名(参数名) [抛出的异常类型])

符合含有
*0到多个符合
方法参数中表示任意个参数,用在报名后表示当前包及其子包
+用在类名后表示当前类及其子类,用在接口后表接口及其实现

示例:

execution(public * *(. .))
指定切入点为:任意公共方法。
execution(* set *(. .))
指定切入点为:任何一个以“set”开始的方法。
execution(* com.xyz.service.*.*(. .))
指定切入点为:定义在service包里的任意类的任意方法。
execution(* com.xyz.service. .*.*(. .))
指定切入点为:定义在service包或者子包里的任意类的任意方法。“..”出现在类名中时,
后面必须跟“*”,表示包、子包下的所有类。
execution(* *.service.*.*(. .))
指定只有一级包下的serivce子包下所有类(接口)中的所有方法为切入点
execution(* *. .service.*.*(. .))
指定所有包下的serivce子包下所有类(接口)中的所有方法为切入点
4. 通知类型
通知类型说明
前置通知目标方法执行之前调用
后置通知目标方法执行完成之后调用
环绕通知目标方法执行前后都会调用方法,且能增强结果
异常处理通知目标方法出现异常调用
最终通知无论程序执行是否正常,该通知都会执行。类似于try…catch中finally代码块
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/691818.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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