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"); } }