AOP是Aspect Oriented Programming,即面向切面编程。
那什么是AOP?
我们先回顾一下OOP:Object Oriented Programming,OOP作为面向对象编程的模式,获得了巨大的成功,OOP的主要功能是数据封装、继承和多态。
而AOP是一种新的编程方式,它和OOP不同,OOP把系统看作多个对象的交互,AOP把系统分解为不同的关注点,或者称之为切面(Aspect)。(个人理解:假如每个逻辑是一条条的竖线,那AOP则是一条与这些竖线相交的一条横线,将自己的逻辑横插在所有设置AOP的业务逻辑中)
使用spring容器方式使用AOP注解:
引包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
如果要封装AOP功能类,注解上要加@Component,意思为将这个类注册为bean,还要加@Aspect,这是标注该类为aop切面功能类
// 在执行UserService的每个方法前执行:
@Before("execution(public * com.itranswarp.learnjava.service.UserService.*(..))")
public void doAccessCheck() {
System.err.println("[Before] do access check...");
}
// 在执行MailService的每个方法前后执行:
@Around("execution(public * com.itranswarp.learnjava.service.MailService.*(..))")
public Object doLogging(ProceedingJoinPoint pjp) throws Throwable {
System.err.println("[Around] start " + pjp.getSignature());
Object retVal = pjp.proceed();
System.err.println("[Around] done " + pjp.getSignature());
return retVal;
}
观察doAccessCheck()
方法,我们定义了一个@Before
注解,后面的字符串是告诉AspectJ应该在何处执行该方法,这里写的意思是:执行UserService
的每个public
方法前执行doAccessCheck()
代码。
再观察doLogging()
方法,我们定义了一个@Around
注解,它和@Before
不同,@Around
可以决定是否执行目标方法,因此,我们在doLogging()
内部先打印日志,再调用方法,最后打印日志后返回结果。
在LoggingAspect
类的声明处,除了用@Component
表示它本身也是一个Bean外,我们再加上@Aspect
注解,表示它的@Before
标注的方法需要注入到UserService
的每个public
方法执行前,@Around
标注的方法需要注入到MailService
的每个public
方法执行前后。