Spring AOP原理详解及实例
1.Spring AOP简介
2.AOP与OOP对比
3.AOP使用场景
4.AOP相关概念
5.AOP实例
5.1 基于xml配置方式
5.2 基于注解配置方式
5.3 @AspectJ切点函数
6.可能出现的问题及解决方法
6.1 java.lang.IllegalArgumentException: error at :: 0 can’t find referenced pointcut……
观前提示:
本文所使用的Eclipse版本为Photon Release (4.8.0),IDEA版本为ultimate 2019.1,JDK版本为1.8.0_141,Tomcat版本为9.0.12。
1.Spring AOP简介
2.AOP与OOP对比
AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单划分。
而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。
上面的陈述可能过于理论化,举个简单的例子,对于“雇员”这样一个业务实体进行封装,自然是OOP/OOD的任务,我们可以为其建立一个“Employee”类,并将“雇员”相关的属性和行为封装其中。而用AOP设计思想对“雇员”进行封装将无从谈起。
同样,对于“权限检查”这一动作片断进行划分,则是AOP的目标领域。而通过OOD/OOP对一个动作进行封装,则有点不伦不类。
换而言之,OOD/OOP面向名词领域,AOP面向动词领域。
3.AOP使用场景
AOP用来封装横切关注点,具体可以在下面的场景中使用:
4.AOP相关概念
通知/增强(Advice): 在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。spring aop advice的类型:
1、前置通知(before advice),在目标方法执行之前执行。
2、返回后通知(after returning advice),在方法正常执行结束之后的通知,可以访问到方法的返回值。
3、抛出异常后通知(after throwing advice),在目标方法出现异常时执行的代码,可以访问到异常对象,且可以指定出现特定异常执行此方法。
4、后置通知:(after[finally] advice),在目标方法执行之后执行(无论是否发生异常)。
5、环绕通知:(around advice),可以实现上述所有功能。
5.AOP实例
需要的jar包:Jar包链接详情点我
需要的jar包
aspectjrt-1.9.2.jar、aspectjweaver-1.9.2.jar
5.1 基于xml配置方式
这里我使用的是Eclipse
注:aop:aspect 子节点还可配置
日志类LogAop.java
package cn.com.demo.aop;
public class LogAop {
public void beforeAdvice() {
System.out.println("beforeAdvice");
}
public void afterAdvice() {
System.out.println("afterAdvice");
}
} UserService.java
package cn.com.demo.service;
public class UserService {
public void insertUser() {
System.out.println("插入用户成功");
}
public boolean updateUser() {
System.out.println("更新用户成功");
return true;
}
} 测试类TestAop
package cn.com.demo.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.demo.service.UserService;
public class TestAop {
private ClassPathXmlApplicationContext ac;
@Before
public void before() {
ac = new ClassPathXmlApplicationContext("*/applicationContext.xml");
}
@Test
public void test() {
try {
UserService userService = (UserService) ac.getBean("userService");
userService.insertUser();
userService.updateUser();
} catch (Exception e) {
e.printStackTrace();
}
}
} 5.2 基于注解配置方式
这里我使用的是Eclipse
package cn.com.demo.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LogAop {
@Pointcut("execution(* cn.com.demo.service.UserService.insertUser(..))")
public void ponitCut() {
}
@Before("ponitCut()")
public void beforeAdvice() {
System.out.println("beforeAdvice");
}
@After("ponitCut()")
public void afterAdvice() {
System.out.println("afterAdvice");
}
//环绕通知。注意要有ProceedingJoinPoint参数传入
@Around("ponitCut()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("注解类型环绕通知..环绕前");
pjp.proceed();//执行方法
System.out.println("注解类型环绕通知..环绕后");
}
} UserService.java
package cn.com.demo.service;
public class UserService {
public void insertUser() {
System.out.println("插入用户成功");
}
public boolean updateUser() {
System.out.println("更新用户成功");
return true;
}
} 测试类TestAop
package cn.com.demo.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.demo.service.UserService;
public class TestAop {
private ClassPathXmlApplicationContext ac;
@Before
public void before() {
ac = new ClassPathXmlApplicationContext("*/applicationContext.xml");
}
@Test
public void test() {
try {
UserService userService = (UserService) ac.getBean("userService");
userService.insertUser();
} catch (Exception e) {
e.printStackTrace();
}
}
} 5.3 @AspectJ切点函数
参考文章:@AspectJ切点函数详解
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/132200.html