AI

spring之AOP笔记(IDEA)

唐某2020-11-14 22:55:19160

spring之AOP笔记(IDEA)

什么是AOP(面向切面)

传统代码遇见的问题

代码臃肿冗余,复用性不高,模块之间耦合度高

初步解决方法

将大量重复使用的代码块抽取成一个个的方法,降低代码冗余,但是这解决不了根本性的问题,即代码的耦合度没有降低,

如果需求变了,那么我们肯定是要修改源代码,如果代码庞大,这种重复性的修改无疑做着无用功,所以AOP思想诞生了

AOP思想

首先AOP是基于动态代理的思想,在不改变原有类(**被代理类)的前提下,创建新生的类(代理类)**来增强原有的类

起名叫AOP呢,形象的说,AOP思想是将需求代码块插入原有类

基于Annotation和bean.xml

bean.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="mySpring"></context:component-scan>
    <!--开启注解aop控制-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>
创建目标类接口
java 复制代码
package mySpring.service;

/**
 * 模拟业务层
 */
public interface IAccountService {
    void saveAccount();
    void updateAccount(int id);
    int deleteAccount();
}
创建目标类
java 复制代码
package mySpring.service.impl;

import mySpring.service.IAccountService;
import org.springframework.stereotype.Service;

@Service("accountService")
public class AccountService implements IAccountService {
    @Override
    public void saveAccount() {
        System.out.println("saveAccount......");
    }

    @Override
    public void updateAccount(int id) {
        System.out.println("updateAccount......" + id);

    }
    @Override
    public int deleteAccount() {
        System.out.println("deleteAccount......");
        return 0;
    }
}

先在有新的需求,想在每个方法执行前输入一些东西(这里以日志输出为例)

需要为这个目标类(被代理对象)找到一个代理类

创建代理类Logger
java 复制代码
package mySpring.utils;

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

@Component("logger")
@Aspect//申明为切面类(代理类)
public class Logger {
    //	代理谁?表达式指定
    @Pointcut("execution(* mySpring.service.IAccountService.*(..))")
    private void pt() {
    }
	
    /**
      *	执行相关方法前的操作
      *	前置
      */
    @Before("pt()")	//指定切点pointcut
    public void beforeMethod() {
        System.out.println("前置");
    }
    
    /**
      *	执行相关方法后的操作
      *	后置
      */
    @AfterReturning("pt()")
    public void returnMethod(JoinPoint joinPoint) throws Throwable {
        System.out.println("后置");
    }
    
    /**
      *	执行相关方法异常时会加的操作
      *	异常
      */
    @AfterThrowing("pt()")
    public void throwMethod(JoinPoint joinPoint) throws Throwable {
        System.out.println("异常");

    }
    

广告