1. 如果没有Spring框架,我们需要在每个service的方法中都添加记录日志的方法,如下:
public List<User> findUserList() {
System.out.println("execute method findUserList");
return this.userDao.findUserList();
}
2. 有了Spring框架,通过@Aspect注解 定义了切面,这个切面中定义了拦截所有service中的方法,并记录日志; 可以明显看到,框架将日志记录和业务需求的代码解耦了,不再是侵入式的了
@Aspect
public class LogAspect {
/**
* aspect for every methods under service package.
*/
@Around("execution(* tech.pdai.springframework.service.*.*(..))")
public Object businessService(ProceedingJoinPoint pjp) throws Throwable {
// get attribute through annotation
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
System.out.println("execute method: " + method.getName());
// continue to process
return pjp.proceed();
}
}
3. 引入以下框架原理:
- Spring 框架通过定义切面, 通过拦截切点实现了不同业务模块的解耦,这个就叫面向切面编程 - Aspect Oriented Programming (AOP)
- 为什么@Aspect注解使用的是aspectj的jar包呢?这就引出了Aspect4J和Spring AOP的历史渊源,只有理解了Aspect4J和Spring的渊源才能理解有些注解上的兼容设计
- 如何支持更多拦截方式来实现解耦, 以满足更多场景需求呢? 这就是@Around, @Pointcut... 等的设计
- 那么Spring框架又是如何实现AOP的呢? 这就引入代理技术,分静态代理和动态代理,动态代理又包含JDK代理和CGLIB代理等