Spring AOP

AOP简介

AOP(Aspect Orient Programming),面向切面编程,是面向对象编程OOP的一种补充。在运行时,动态的将代码切入到类的指定方法、指定位置上的编程思想。
优点:降低代码之间的耦合,提高代码的复用性。
spring底层采用了动态代理的方式实现aop。采用了两种代理:
JDK的动态代理:如果贝代理类实现了接口,默认jdk。(使用了反射,耦合度低)
CGLIB的动态代理:如果累没有实现接口,会使用CGLIB动态代理。(使用字节码处理器ASM,性能好)

AOP常用术语

1,目标对象(Target):指将要被增强的对象。
2,切面(Aspect):指非业务逻辑。
3,连接点(JoinPoint):业务接口中的方法,可以被切面织入的方法
4,切入点(PointCut):指切面具体织入的方法
5,通知(Advice):通知是切面的一种实现。
6,织入(Weaving):将切面代码插入到目标对象的过程。(invoke)
7,AOP代理(Aop proxy)
在这里插入图片描述

目前spring用得是AspectJ对AOP的实现

Spring 2.0引入了,下面是目前spring AOP的注解实现方式

创建一个Module aoptest

1,添加以下目录结构,添加xml配置文件
在这里插入图片描述
2,pom.xml文件加入依赖

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.6.12</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.0.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.jetbrains</groupId>
      <artifactId>annotations-java5</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

3,添加以下目录结构
在这里插入图片描述
目标类的内容:

@Service("userService")
public class UserServiceIpml implements UserService {

    @Override
    public void addUser(){
        System.out.println("执行addUser()方法");
    }

    @Override
    public void deleteUser(){
        System.out.println("执行deleteUser()方法");
    }

    @Override
    public int updateUser(){
        System.out.println("执行updateUser()方法");
        return 1024;
    }

    @Override
    public void selectUser(){
        System.out.println("执行selectUser()方法");
    }

    @Override
    public void selectUserById(int id ) throws Exception{
        System.out.println("执行selectUserById()方法");
        if(id==0){
            throw new Exception();
        }
    }
}

切面内容:

@Aspect
@Component
public class MyAspect {

    @Before("execution(*  *..UserServiceIpml.addUser())")
    public void before(){
        System.out.println("==============前置通知==============");
    }

    @After("execution(*  *..UserServiceIpml.selectUser())")
    public void after(){
        System.out.println("==============最终通知==============");
    }

    @AfterReturning(value="execution(*  *..UserServiceIpml.updateUser())",returning="result")
    public void afterReturning(int result){
        System.out.println("==============后置通知=============="+result);
    }

    @AfterThrowing(value="execution(*  *..UserServiceIpml.selectUserById(..))",throwing = "e")
    public void afterThrowing(Exception e){
        System.out.println("==============异常通知=============="+e);
    }

    @Around("execution(*  *..UserServiceIpml.deleteUser())")
    public Object around(ProceedingJoinPoint pjp)throws Throwable{
        System.out.println("==============环绕通知:前==============");
        Object proceed= pjp.proceed();
        System.out.println("==============环绕通知:后==============");
        return proceed;
    }

}

配置文件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
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
   <context:component-scan base-package="cn.test"/>
   <aop:aspectj-autoproxy/>
</beans>

测试类:

public class test01 {

    @Test
    public void testAop(){
        ApplicationContext context=new ClassPathXmlApplicationContext( "applicationContext.xml");
        UserService service=(UserService) context.getBean("userService");
        service.addUser();
        service.selectUser();
        service.deleteUser();
        service.updateUser();
        try {
           service.deleteUser();
        }catch (Exception e){
           e.printStackTrace();
        }
        //关闭容器
        //((ClassPathXmlApplicationContext)context).close();
    }
}

解析:在切面和目标类加了注解,并在配置文件加入了扫描包的配置和开启动态代理的配置
注意:扫描包最好一开始就创建好,在各个pom.xml文件配好
动态代理:https://www.iteye.com/blog/chenjumin-2437690
springboot:https://www.cnblogs.com/onlymate/p/9630788.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值