学而时习之,不亦悦乎!
一、AOP核心概念
Aspect: 横跨多个类的模块化概念. Join point: 程序执行的一个点. 比如方法进入,抛出异常等 Advice: 在一个特殊 join point采取的动作. Pointcut: 匹配 join point的断言. Introduction: 为一个类声明额外的字段或者方法. Target object: 被一个或多个切面增强的对象. AOP proxy: 为了实现切面而被AOP框架创建的对象. Weaving: 链接切面于其他应用类型或者对象从而创建一个被增强的类.
二、Advice类型
Before advice: Advice that runs before a join point but that does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception). After returning advice: Advice to be run after a join point completes normally (for example, if a method returns without throwing an exception). After throwing advice: Advice to be executed if a method exits by throwing an exception. After (finally) advice: Advice to be executed regardless of the means by which a join point exits (normal or exceptional return). Around advice: Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. Around advice can perform custom behavior before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception.
三、Spring AOP的能力和目标
1.纯Java实现 2.为了与SpringIOC无缝集成AOP能力 3.不是一个AOP的完整解决方案,只是提供AOP的能力 4.与AspectJ不是竞争关系,而是互补。
四、Spring AOP包概述
五、核心接口
要对哪个类的哪些方法进行AOP拦截?
public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher(); }
要对拦截到的方法做什么?
public interface MethodInterceptor extends Interceptor { Object invoke(MethodInvocation invocation) throws Throwable; }
所有通知都是Advice的子接口,都是通过适配器模式转向MethodIntercepter,适配器类都在
org.springframework.aop.framework.adapter包下
封装所有的Advice类型Advisor
public interface Advisor { Advice EMPTY_ADVICE = new Advice() {}; Advice getAdvice(); boolean isPerInstance(); }
封装PointCut和Advice
public interface PointcutAdvisor extends Advisor { Pointcut getPointcut(); }
AopProxy代理创建
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } /** * Determine whether the supplied {@link AdvisedSupport} has only the * {@link org.springframework.aop.SpringProxy} interface specified * (or no proxy interfaces specified at all). */ private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { Class<?>[] ifcs = config.getProxiedInterfaces(); return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]))); } }
基于Cglib和JDK代理的区别?
1.JDK代理只能代理接口,所以只有接口的方法会被拦截 2.Cglib可以代理类,非private的方法都可以被拦截
手写代理
单个bean代理:ProxyFactory 、ProxyFactoryBean 自动代理:BeanNameAutoProxyCreator、InfrastructureAdvisorAutoProxyCreator
单个和自动是什么意思?
单个:手动指定要代理的bean,advice,然后调用getProxy获取他的代理对象。每次只能创建一个代理对象 自动:指定要代理的bean的规则,指定使用的advice,IOC创建对象时自动对bean进行代理创建,通过IOC获取到的对象为代理对象
Spring如何整合AspectJ?适配
引介通知实现:
DelegatePerTargetObjectIntroductionInterceptor
参考:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aop
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aop-api