Spring AOP初步理解及使用(二)

简介: Spring AOP初步理解及使用

Spring AOP初步理解及使用(一)https://developer.aliyun.com/article/1426135


(3)切面类
package org.ymx.service;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
 * 注解@Aspect标识该类为切面类
 */
@Component
@Aspect
public class ServiceAspect {
    /**
     * 通过注解@Pointcut定义切点,stuSayHello()只是一个标识,无所谓是什么,
     * 方法中内容本身也是空的,使用该切点的地方直接通过标识stuSayHello()引用切点表达式。
     */
    @Pointcut("execution(* org.ymx.service.impl.StudentServiceImpl.sayHello(..))")
    public void stuSayHello() {
    }
    /**
     * 说话之前--张开嘴巴
     */
    @Before("stuSayHello()")
    public void openMouth() {
        System.out.println("Opens his mouth");
    }
    /**
     * 说话之前--睁开眼睛
     */
    @Before("stuSayHello()")
    public void openEyes() {
        System.out.println("Open one's eyes");
    }
    /**
     * 说话之后--微笑
     */
    @After("stuSayHello()")
    public void smile() {
        System.out.println("Smile");
    }
}

(4)AOP全局配置
package org.ymx.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
 * Jdk代理:基于接口的代理,一定是基于接口,会生成目标对象的接口的子对象。
 * Cglib代理:基于类的代理,不需要基于接口,会生成目标对象的子对象。
 *
 * 1. 注解@EnableAspectJAutoProxy开启代理;
 *
 * 2. 如果属性proxyTargetClass默认为false, 表示使用jdk动态代理织入增强;
 *
 * 3. 如果属性proxyTargetClass设置为true,表示使用Cglib动态代理技术织入增强;
 *
 * 4. 如果属性proxyTargetClass设置为false,但是目标类没有声明接口,
 *    Spring aop还是会使用Cglib动态代理,也就是说非接口的类要生成代理都用Cglib。
 */
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan("org.ymx.service")
public class AopConfig {
}
(5)测试
package test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.ymx.config.AopConfig;
import org.ymx.service.StudentService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AopConfig.class) //加载全局配置
public class test01 {
    @Autowired
    private StudentService studentService;
    @Test
    public void Test01(){
        studentService.sayHello();
    }
}

测试时一定要加载全局配置@ContextConfiguration(classes = AopConfig.class)不然AOP不起作用

3 实现方式二

与上述方式实现唯一不同点在于切面类使用的 @Around注解来替代@Before和@After

package org.ymx.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
 * 注解@Aspect标识该类为切面类
 */
@Component
@Aspect
public class ServiceAspect {
    /**
     * 通过注解@Pointcut定义切点,stuSayHello()只是一个标识,无所谓是什么,
     * 方法中内容本身也是空的,使用该切点的地方直接通过标识stuSayHello()引用切点表达式。
     */
    @Pointcut("execution(* org.ymx.service.impl.StudentServiceImpl.sayHello(..))")
    public void stuSayHello() {
    }
    @Around("stuSayHello()")
    public void testAround(ProceedingJoinPoint jp) {
        try {
            System.out.println("Opens his mouth");
            System.out.println("Open one's eyes");
            jp.proceed();//执行方法
            System.out.println("Smile");
        } catch (Throwable e) {
            System.out.println("没说出来");
        }
    }
}
4 测试结果

五、AOP实战(注解版)

1 简介

StudentService类具有SayHello()方法表示说Hello,但是在学生和别人说”Hello“之前,必须张开嘴巴和睁开眼睛,说完“Hello”之后再来一个回眸微笑,图示如下:

2 实现方式一
(1)pom依赖
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
(2)Service接口和实现类
## 接口:
package org.ymx.service;
public interface StudentService {
     void sayHello();
}
## 实现类:
package org.ymx.service.impl;
import org.springframework.stereotype.Service;
import org.ymx.service.StudentService;
@Service
public class StudentServiceImpl implements StudentService {
    @Override
    public void sayHello() {
        System.out.println("Hello");
    }
} 
相关文章
|
21天前
|
XML 监控 安全
Spring特性之一——AOP面向切面编程
Spring特性之一——AOP面向切面编程
26 1
|
21天前
|
运维 Java 程序员
Spring5深入浅出篇:基于注解实现的AOP
# Spring5 AOP 深入理解:注解实现 本文介绍了基于注解的AOP编程步骤,包括原始对象、额外功能、切点和组装切面。步骤1-3旨在构建切面,与传统AOP相似。示例代码展示了如何使用`@Around`定义切面和执行逻辑。配置中,通过`@Aspect`和`@Around`注解定义切点,并在Spring配置中启用AOP自动代理。 进一步讨论了切点复用,避免重复代码以提高代码维护性。通过`@Pointcut`定义通用切点表达式,然后在多个通知中引用。此外,解释了AOP底层实现的两种动态代理方式:JDK动态代理和Cglib字节码增强,默认使用JDK,可通过配置切换到Cglib
|
1天前
|
Java Spring
【JavaEE进阶】 Spring AOP源码简单剖析
【JavaEE进阶】 Spring AOP源码简单剖析
|
1天前
|
Java Spring
【JavaEE进阶】 Spring AOP详解
【JavaEE进阶】 Spring AOP详解
|
1天前
|
数据采集 Java 程序员
【JavaEE进阶】 Spring AOP快速上手
【JavaEE进阶】 Spring AOP快速上手
|
7天前
|
Java Spring
|
7天前
|
Java Spring
|
7天前
|
前端开发 Java Maven
Spring AOP
Spring AOP
16 1
|
8天前
|
数据采集 XML 监控
Spring AOP
Spring AOP
34 2
|
12天前
|
Java Spring 容器
Spring AOP 代码案例
Spring AOP 代码案例
27 1