aop面向切面编程,拦截指定函数,在调用前,后作一些其他操作
===== spring中有2种方式实现AOP =====
- 通过注解方式(建议使用,简单)
- 通过xml配置文件方式
===== mvn 依赖 =====
org.springframework
spring-context
4.1.4.RELEASE
org.springframework
spring-context-support
4.1.4.RELEASE
org.springframework
spring-aop
4.1.4.RELEASE
org.aspectj
aspectjrt
1.6.11
org.aspectj
aspectjweaver
1.6.11
===== 方式1(注解) =====
=== 要拦截的函数 ===
package aop.annotation;
public class HelloWorld {
public void sayHello() {
System.out.println("hello world");
}
}
=== 拦截后要执行的操作 ===
package aop.annotation;
import org.aspectj.lang.JoinPoint;
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.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class Annotation {
// 定义拦截函数,aspect函数的作用域相当于一个id
@Pointcut("execution(* aop.annotation.HelloWorld.sayHello(..))")
public void aspectBefore(){ }
@Pointcut("execution(* aop.annotation.HelloWorld.sayHello(..))")
public void aspectAfter(){ }
/**
* aspectBefore函数对应的函数被拦截前执行,doBefore函数
*/
@Before("aspectBefore()")
private void doBefore(JoinPoint joinPoint) {
System.out.println("-----doBefore().invoke-----");
}
/**
* aspectAfter函数对应的函数被拦截前执行,doBefore函数
*/
@After("aspectAfter()")
private void doAfter(JoinPoint joinPoint) {
System.out.println("-----doAfter().invoke-----");
}
}
=== main函数 ===
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("spring_aop_annotation.xml");
HelloWorld userManager = (HelloWorld)factory.getBean("helloWorld");
userManager.sayHello();
}
=== xml配置 ===
===== 方式2(xml配置) =====
=== 要拦截的函数 ===
package aop.xml;
public class UserManagerImpl {
public String findUserById(int userId) {
System.out.println("---------HelloWorld.sayHello()--------");
if (userId <= 0) {
throw new IllegalArgumentException("该用户不存在!");
}
return "张三";
}
}
=== 拦截后要执行的操作 ===
package aop.xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Advice通知类
* 测试after,before,around,throwing,returning Advice.
* @author Admin
*
*/
public class XMLAdvice {
/**
* 在核心业务执行前执行,不能阻止核心业务的调用。
* @param joinPoint
*/
private void doBefore(JoinPoint joinPoint) {
System.out.println("-----doBefore().invoke-----");
System.out.println(" 此处意在执行核心业务逻辑前,做一些安全性的判断等等");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doBefore()------");
}
/**
* 手动控制调用核心业务逻辑,以及调用前和调用后的处理,
*
* 注意:当核心业务抛异常后,立即退出,转向After Advice
* 执行完毕After Advice,再转到Throwing Advice
* @param pjp
* @return
* @throws Throwable
*/
private Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("-----doAround().invoke-----");
System.out.println(" 此处可以做类似于Before Advice的事情");
//调用核心逻辑
Object retVal = pjp.proceed();
System.out.println(" 此处可以做类似于After Advice的事情");
System.out.println("-----End of doAround()------");
return retVal;
}
/**
* 核心业务逻辑退出后(包括正常执行结束和异常退出),执行此Advice
* @param joinPoint
*/
private void doAfter(JoinPoint joinPoint) {
System.out.println("-----doAfter().invoke-----");
System.out.println(" 此处意在执行核心业务逻辑之后,做一些日志记录操作等等");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doAfter()------");
}
/**
* 核心业务逻辑调用正常退出后,不管是否有返回值,正常退出后,均执行此Advice
* @param joinPoint
*/
private void doReturn(JoinPoint joinPoint) {
System.out.println("-----doReturn().invoke-----");
System.out.println(" 此处可以对返回值做进一步处理");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doReturn()------");
}
/**
* 核心业务逻辑调用异常退出后,执行此Advice,处理错误信息
* @param joinPoint
* @param ex
*/
private void doThrowing(JoinPoint joinPoint,Throwable ex) {
System.out.println("-----doThrowing().invoke-----");
System.out.println(" 错误信息:"+ex.getMessage());
System.out.println(" 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等");
System.out.println(" 可通过joinPoint来获取所需要的内容");
System.out.println("-----End of doThrowing()------");
}
}
=== main函数 ===
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("spring_aop_xml.xml");
UserManagerImpl userManager = (UserManagerImpl)factory.getBean("userManager");
//可以查找张三
userManager.findUserById(1);
System.out.println("=====我==是==分==割==线=====");
try {
// 查不到数据,会抛异常,异常会被AfterThrowingAdvice捕获
userManager.findUserById(0);
} catch (IllegalArgumentException e) {
}
}
=== xml配置 ===