如果你没有把握做到,最好就不要承诺,你什么也不承诺,至少别人不会看不起你。
几个概念
- 横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
- Aspect(切面):用于定义切入点和通知的类
- Joint point(连接点):程序执行过程中明确的点,一般是方法的调用。被拦截到的点,在Spring只支持方法类型的连接点。
- Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
- Advice(增强):AOP在特定的切入点上执行的增强处理,有before(前置),after(后置),afterReturning(最终),afterThrowing(异常),around(环绕)。
- Target(目标对象):织入 Advice 的目标对象.。
- Weaving(织入): 将切面应用到目标对象并导致代理对象创建的过程
- introduction(引入):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段
案例
@Aspect
public class LogAspect {
@Pointcut("@annotation(com.demo.Log)")
private void pointcut() {
}
@AfterReturning(value = "pointcut()", returning = "result")
public void doBefore(JoinPoint joinPoint, Object result) {
}
}
这里 LogAspect 通过 @Aspect 注解声明了一个切面,该切面用于日志处理。
@annotation(com.demo.Log) 定义了一系列连接点,然后通过 @Pointcut 切入。 @AfterReturning 用于通知程序什么时候调用注解,并实现代理操作。
AOP 概念思维导图
8.AOP思维导图.png前面概念介绍了,那么Spring中如何实现AOP呢?
静态代理
静态代理是程序实现时,直接写入代码的,代理类和实现类是固定不可变的。
public interface HelloWord{
void hello();
}
public class HelloWordImpl implements HelloWord{
//切入点
@Override
public void hello(){
System.out.println("hello!");
}
}
public class HelloWordProxy{
private HelloWord helloWord;
public HelloWordProxy(HelloWord demo){
helloWord=demo;
}
public void hello(){
System.out.println("before");
helloWord.hello();
System.out.println("end");
}
}
public static void main(String ... args){
HelloWord src=new HelloWordImpl();
HelloWord proxy=new HelloWordProxy(src);
proxy.hello();
}
上面代码是静态代理实现AOP的基本思路,HelloWordProxy 代理中 在调用 hello 前与后都做了输出处理,可以理解为一种环绕模式。
动态代理
先看一个 Cglib代理:
public static class HelloWord {
public void hello(){
System.out.println("hello!");
}
}
public static void main(String ... args){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(HelloWord.class);
enhancer.setCallback((MethodInterceptor) (
obj, method, methodArgs, methodProxy) -> {
System.out.println("before");
Object result =methodProxy.invokeSuper(obj,methodArgs);
System.out.println("after");
return result;
});
HelloWord helloWord=(HelloWord) enhancer.create();
helloWord.hello();
}
程序输出:
before
hello!
after
可以看的这里通过 MethodInterceptor 方法实现环绕通知。
spring aop 实现原理
- ProxyFactory
-
ProxyFactoryBean
8.ProxyFactoryBean.png
网友评论