• spring_aop_学习笔记


    aop及其实现的方法

    1 什么是aop

    aop 即 面向切面编程

    横切关注点: 跨越应用程序的多个模块的方法或功能,与我们业务逻辑无关的,但是需要我们关注的部分,就是横切关注点。如日志,安全,缓存,事务等等。

    切面(Aspect): 切面是一个横切关注点的模块化的特殊对象,即,他是一个类。

    通知(advice): 切面必须完成的工作,即,他是一个方法。

    目标(target): 被通知的对象。

    代理(proxy): 向目标对象应用通知之后创建的对象。

    切入点(pointcut): 切面通知执行的地点。

    连接点(joinPoint): 被拦截到的程序执行点

    2 aop的作用

    AOP 主要用来解决,在不改变原有业务逻辑的情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。

    3 aop的好处

    1、减少重复代码
    2、提高开发效率
    3、维护方便

    4 实现aop的三种方式

    准备工作
    采用一个对用户的CRUD的例子
    定义一个CRUD接口

    public interface UserService {
        void add();
        void delete();
        void update();
        void select();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    接口实现类

    public class UserServiceImpl implements UserService{
        @Override
        public void add() {
            System.out.println("增加了一个User!");
        }
    
        @Override
        public void delete() {
            System.out.println("删除了一个User!");
        }
    
        @Override
        public void update() {
            System.out.println("更新了一个User!");
        }
    
        @Override
        public void select() {
            System.out.println("查询了一个User!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    log类

    import org.springframework.aop.MethodBeforeAdvice;
    
    import java.lang.reflect.Method;
    
    public class Log implements MethodBeforeAdvice {
        //method 要执行的目标对象的方法
        //args 参数
        //target 目标对象
        @Override
        public void before(Method method, Object[] args, Object target) throws Throwable {
            System.out.println("[log] "+target.getClass().getName()+"的"+method.getName()+"被执行了");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    AfterLog类

    import org.springframework.aop.AfterReturningAdvice;
    
    import java.lang.reflect.Method;
    
    public class AfterLog implements AfterReturningAdvice {
        //returnValue 返回值
        @Override
        public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
            System.out.println("执行了"+method.getName()+"返回的值为:"+returnValue);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    配置spring applicationContext.xml
    一定要导入AOP的约束

    
    <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
    		https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
    		https://www.springframework.org/schema/aop/spring-aop.xsd>
    
        "userService" class="com.wq.service.UserServiceImpl"/>
        <bean id="log" class="com.wq.log.Log"/>
        <bean id="afterLog" class="com.wq.log.AfterLog"/>
        
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试类

    import com.wq.service.UserService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
        @Test
        public void test1(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = context.getBean("userService", UserService.class);
            userService.add();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.1 spring的API接口实现aop

    配置xml如下

    
    <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
    		https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
    		https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean id="userService" class="com.wq.service.UserServiceImpl"/>
        <bean id="log" class="com.wq.log.Log"/>
        <bean id="afterLog" class="com.wq.log.AfterLog"/>
    
        
        
        <aop:config>
            
            <aop:pointcut id="pointcut" expression="execution(* com.wq.service.UserServiceImpl.*(..) )"/>
    
            
            <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
            <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
        aop:config>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    测试示例

    [log] com.wq.service.UserServiceImpl的add被执行了
    增加了一个User!
    执行了add返回的值为:null
    
    • 1
    • 2
    • 3

    4.2 自定义实现aop

    自定义pointcut

    public class DiyPointcut {
        public void before(){
            System.out.println("-------方法执行前------");
        }
        public void after(){
            System.out.println("-------方法执行后------");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在xml中注册
    xml配置如下

    
    <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
    		https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
    		https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean id="userService" class="com.wq.service.UserServiceImpl"/>
        <bean id="log" class="com.wq.log.Log"/>
        <bean id="afterLog" class="com.wq.log.AfterLog"/>
        <bean id="diy" class="com.wq.diy.DiyPointcut"/>
        
        <aop:config>
            
            <aop:aspect id="diy" ref="diy">
                
                <aop:pointcut id="point" expression="execution(* com.wq.service.UserServiceImpl.*(..))"/>
                
                <aop:before method="before" pointcut-ref="point"/>
                <aop:after method="after" pointcut-ref="point"/>
            aop:aspect>
        aop:config>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    测试示例

    -------方法执行前------
    增加了一个User!
    -------方法执行后------
    
    • 1
    • 2
    • 3

    4.3 注解实现aop

    自定义pointcut

    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class AnnotationPointcut {
        @Before("execution(* com.wq.service.UserServiceImpl.*(..))")
        public void before(){
            System.out.println("-------方法执行前------");
        }
        @After("execution(* com.wq.service.UserServiceImpl.*(..))")
        public void after(){
            System.out.println("-------方法执行后------");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这里采用的是注解方式实现的
    @aspect 标注的是这个类是一个切面
    @Before("execution(* com.wq.service.UserServiceImpl.*(..))")@After("execution(* com.wq.service.UserServiceImpl.*(..))")与第二种方式的

    
                <aop:pointcut id="point" expression="execution(* com.wq.service.UserServiceImpl.*(..))"/>
                
                <aop:before method="before" pointcut-ref="point"/>
                <aop:after method="after" pointcut-ref="point"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    作用相同

    xml配置如下

    因为上面我采用的是全注解实现,所以需要添加注解的约束及配置

    
    <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"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
    		https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
    		https://www.springframework.org/schema/aop/spring-aop.xsd
    		http://www.springframework.org/schema/context
    		https://www.springframework.org/schema/context/spring-context.xsd">
        
        <context:component-scan base-package="com"/>
        <context:annotation-config/>
    
        <bean id="userService" class="com.wq.service.UserServiceImpl"/>
        <bean id="log" class="com.wq.log.Log"/>
        <bean id="afterLog" class="com.wq.log.AfterLog"/>
    
        
        
        <aop:aspectj-autoproxy/>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    测试示例

    -------方法执行前------
    增加了一个User!
    -------方法执行后------
    
    • 1
    • 2
    • 3
  • 相关阅读:
    FPGA之旅设计99例之第十例-----串口上位机模拟OLED屏
    WPF基础知识系例
    华为数字化转型之道 方法篇 第四章 用变革的方法确保规划落地
    微电网单台并网逆变器PQ控制matlab仿真模型
    Batbot智慧能源管理云平台:拥抱数字化,提高能源效率!
    【kernel exploit】CVE-2022-32250 nftables错误链表操作导致UAF写的漏洞利用
    记录一次数据库CPU被打满的排查过程
    Java开发二面被疯狂问JVM相关,被整懵了!!
    找斑点(blob)的最小旋转矩形(三)
    <C++>详解vector类
  • 原文地址:https://blog.csdn.net/m0_63962653/article/details/133044963