目录
一、概述
二、SpringAOP运行时增强
三、Spring AOP的常用类
四、Spring AOP源码分析
1.XML 配置
2.ProxyFactoryBean生成AOP代理对象
3.具体的两种代理对象生成源码
1、 JDK动态代理:
2、CGLIB动态代理
五、切点和切面分析
六、参考
Spring AOP动态代理主要是两种方式,JDK动态代理和CGLIB动态代理。
public class ProxyConfig implements Serializable {
private boolean proxyTargetClass = false;
private boolean optimize = false;
boolean opaque = false;
boolean exposeProxy = false;
private boolean frozen = false;
public void copyFrom(ProxyConfig other) {
Assert.notNull(other, "Other ProxyConfig object must not be null");
this.proxyTargetClass = other.proxyTargetClass;
this.optimize = other.optimize;
this.exposeProxy = other.exposeProxy;
this.frozen = other.frozen;
this.opaque = other.opaque;
}
}
以ProxyFactoryBean为例,分析Spring AOP的实现原理。
com.test.Request
logAdvice
ProxyFactoryBean配置目标对象和切面行为Advice,通过其配置的拦截器名称interceptorNames即通知器Advisor将切面应用到目标对象中。
ProxyFactoryBean的功能:
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean// 标记通知器的为全局通知器
public static final String GLOBAL_SUFFIX = "*";// 通知器链是否已经初始化
private boolean advisorChainInitialized = false;// 如果是单例,缓存单例对象
private Object singletonInstance;// 实际上是:new DefaultAdvisorAdapterRegistry();Advisor适配器注册,将Advice适配成Advisor
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
// 创建AOPProxy代理对象的入口
public Object getObject() throws BeansException {
// 初始化通知器链
initializeAdvisorChain();if (isSingleton()) { // 单例
return getSingletonInstance();
}
else { // 原型
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
return newPrototypeInstance();
}
}// 初始化通知器链(同步方法)
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (this.advisorChainInitialized) {
// 如果通知器链已经初始化,直接返回
return;
}if (!ObjectUtils.isEmpty(this.interceptorNames)) { // 如果配置的拦截器名称存在
// 如果没有bean容器,抛出异常
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
}// 全局通知器不能是通知器链中最后一个,除非显示的指定了目标
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
throw new AopConfigException("Target required after globals");
}// 遍历通知器链名称
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
// 如果通知器是全局的
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
// 向容器中添加全局通知器
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
// 否则,不是全局的
else {
// 判断 通知器是否为单例
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) { // 单例模式
// 添加实际的 Advisor/Advice 到链中
advice = this.beanFactory.getBean(name);
}
else { // 原型模式
// 如果是原型的 Advice or Advisor: 创建新的
// 避免通知器链初始化时没有必要的对象创建
advice = new PrototypePlaceholderAdvisor(name);
}
// 将Advice or Advisor添加的链中
addAdvisorOnChainCreation(advice, name);
}
}
}// 设置通知器链初始化标识:已初始化
this.advisorChainInitialized = true;
}// 将Advice or Advisor添加的链中
private void addAdvisorOnChainCreation(Object next, String name) {
// 将提供的Advice、advisor转换为Advisor,以便匹配超类
Advisor advisor = namedBeanToAdvisor(next);
if (logger.isTraceEnabled()) {
logger.trace("Adding advisor with name '" + name + "'");
}
// 加入到通知器链中
addAdvisor(advisor);
}// 将提供的Advice、Advisor转换为Advisor
private Advisor namedBeanToAdvisor(Object next) {
try {
// 包装成Advisor通知器
return this.advisorAdapterRegistry.wrap(next);
}
catch (UnknownAdviceTypeException ex) {
// 如果提供的不是 Advisor or Advice, 抛出异常
throw new AopConfigException("Unknown advisor type " + next.getClass() +
"; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
"which may also be target or TargetSource", ex);
}
}// 单例对象的 代理对象 构造
private synchronized Object getSingletonInstance() {
// singletonInstance 没有缓存单例代理对象,则创建,否则直接返回
if (this.singletonInstance == null) {
// 获取要代理的目标源
this.targetSource = freshTargetSource();
// 如果ProxyFactoryBean设置了自动探测接口属性(默认为True),且没有配置代理接口,且不是目标类的直接代理(ProxyConfig中默认为false)
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// 获取要代理对象的目标类
Class> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
// 获取目标类的接口
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
//初始化共享的单例对象
// 设置是否使用ProxyConfig的默认配置:false,默认使用
super.setFrozen(this.freezeProxy);
// 创建AopProxy对象
this.singletonInstance = getProxy(createAopProxy());
}return this.singletonInstance;
}// 原型对象的 代理对象 构造
private synchronized Object newPrototypeInstance() {
// In the case of a prototype, we need to give the proxy
// an independent instance of the configuration.
// In this case, no proxy will have an instance of this object's configuration,
// but will have an independent copy.
if (logger.isTraceEnabled()) {
logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
}
// 根据当前的工厂类,创建一个代理生成辅助类
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
// 辅助类需要一个新的通知器链和一个新的目标源
TargetSource targetSource = freshTargetSource();
// 代理生成辅助类,复制当前代理生成类的配置,新的目标源和通知器链
copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// 辅助类,设置接口
copy.setInterfaces(
ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
}
// 设置是否冻结默认配置
copy.setFrozen(this.freezeProxy);if (logger.isTraceEnabled()) {
logger.trace("Using ProxyCreatorSupport copy: " + copy);
}
// 通过辅助类创建代理对象,由此可见,每次原型的代理类,都是创建了一个新的copy
return getProxy(copy.createAopProxy());
}}
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry {
// 默认注册三类通知适配器
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}// 将Advice接口类适配为Advisor接口类,即将Advice包装成Advisor
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 如果指定的类型已经是通知器,直接返回
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 如果指定的类型不是Advice类型,直接抛出异常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
// 获取Advice
Advice advice = (Advice) adviceObject;
// 如果Advice是MethodInterceptor类型的
if (advice instanceof MethodInterceptor) {
// 直接返回默认的切点通知器
return new DefaultPointcutAdvisor(advice);
}
// 否则使用注册的Advisor适配器对Advice核查(可自定义)
for (AdvisorAdapter adapter : this.adapters) {
// 核查是否支持
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
// 不支持的通知类型,抛出异常
throw new UnknownAdviceTypeException(advice);
}protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
}
由源码可知,ProxyFactoryBean继承了ProxyCreatorSupport类,所以其本身就是创建AopProxy的工厂bean,其有个属性:AopProxyFactory,默认为DefaultAopProxyFactory;调用createAopProxy方法;
public class ProxyCreatorSupport extends AdvisedSupport {
// AOP proxy 工厂类
private AopProxyFactory aopProxyFactory;//当第一个AOPProxy代理对象被创建时,设置为true
private boolean active = false;// 默认使用DefaultAopProxyFactory生成代理对象
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}// 通过子类的调用
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 调用DefaultAopProxyFactory生成代理对象
return getAopProxyFactory().createAopProxy(this);
}// 激活代理配置,向容器注册代理回调监听器,第一次创建AOP代理时调用
private void activate() {
this.active = true;
for (AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
}
接下来,看下默认工厂的创建方法:
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// ProxyConfig : optimize=false;
// AOP显示优化 或 配置了目标类 或 使用了Spring支持的代理接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 获取AOP配置的目标类
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.");
}
// 如果配置的AOP目标类是接口,或者目标类已经是代理类,使用JDK动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用CGLIB动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 没有显示优化且没有配置目标类且没有使用代理接口,默认使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
}// 确定AdvisedSupport提供的配置,是否只配置了SpringProxy接口或者根本没有实现任何接口
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
// 获取AOP配置的所有接口
Class>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
}
至此,SpringAOP的代理对象生成的流程走完了。
Spring AOP在invoke方法中,调用配置的通知器链;
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
// 代理对象使用的配置
private final AdvisedSupport advised;// 通过 AdvisedSupport 配置构造一个JDK AOP代理对象
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
// 目标类没有通知器链(不需要代理)且 没有配置需要代理的对象
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
// 初始化AOP配置
this.advised = config;
}// 获取AOP代理对象的入口类
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}// 创建AOP代理对象
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
// 获取AOP配置的代理接口
Class>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 查找代理目标的接口是否定义equals和hashcode方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 使用JDK动态代理创建AOP对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}// 通过内省去判断代理接口,是否有equals 和 hashCode方法
private void findDefinedEqualsAndHashCodeMethods(Class>[] proxiedInterfaces) {
for (Class> proxiedInterface : proxiedInterfaces) {
Method[] methods = proxiedInterface.getDeclaredMethods();
for (Method method : methods) {
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}// 实现 InvocationHandler,回调的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
// 通知的目标对象源
TargetSource targetSource = this.advised.targetSource;
Class> targetClass = null;
Object target = null;try {
// 如果目标对象没有实现equals方法且当前调用equals方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 使用 提供的
return equals(args[0]);
}
// 如果目标对象没有实现hashCode方法且当前调用hashCode方法
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
// 如果目标方法只是DecoratingProxy,重定向到代理配置
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 如果AOP配置了通知,使用反射机制调用同名方法
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}Object retVal;
// 如果当前通知暴露了代理,将当前代理变为可用代理
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}// 获取目标方法的拦截器链
List// 如果没有连接器
if (chain.isEmpty()) {
// 使用反射直接调用目标方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建方法回调对象
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 沿着拦截器链,执行通知
retVal = invocation.proceed();
}// 如果方法有返回值,则将代理对象作为方法返回
Class> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
// 如果返回不为void,返回为空,抛出异常
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// 释放目标对象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// 存储当前代理对象
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
调用AopUtils.invokeJoinpointUsingReflection()方法,回调目标类的方法
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {// 利用反射回调目标方法
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
}
class CglibAopProxy implements AopProxy, Serializable {
// 获取代理对象
public Object getProxy(ClassLoader classLoader) {
try {
// 获取要代理的目标类
Class> rootClass = this.advised.getTargetClass();
// 将目标类做为基类(父类)
Class> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) { // 核查目标类是否已经是CGLIB动态代理对象
// 获取其父类
proxySuperClass = rootClass.getSuperclass();
// 获取目标类的接口
Class>[] additionalInterfaces = rootClass.getInterfaces();
// 将目标类的接口添加到AOP配置的接口中
for (Class> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}// 验证基类
validateClassIfNecessary(proxySuperClass, classLoader);// 配置CGLIB的Enhancer(CGLIB的主要操作类)
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 配置
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));Callback[] callbacks = getCallbacks(rootClass);
Class>[] types = new Class>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// 设置回调过滤器
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
// 设置回调方法的类型
enhancer.setCallbackTypes(types);// 生成字节码流并创建代理对象
return createProxyClassAndInstance(enhancer, callbacks);
}
}// 获取目标类的回调通知
private Callback[] getCallbacks(Class> rootClass) throws Exception {
// 优化参数
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();// 根据AOP配置创建一个动态通知拦截器,CGLIB创建的动态代理会自动调用
// DynamicAdvisedInterceptor类的intercept方法对目标对象进行拦截处理
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else {
targetInterceptor = isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
// 创建目标分发器
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};Callback[] callbacks;
// 如果目标是静态的,并且通知链被冻结,则使用优化AOP调用,直接对方法使用
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap(methods.length); for (int x = 0; x < methods.length; x++) {
List}
看下: CglibAopProxy.DynamicAdvisedInterceptor,动态通知拦截器;回调目标类的方法;
private static class DynamicAdvisedInterceptor implements MethodInterceptor {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) { // 如果通知暴露了代理
// 当前代理对象也要被拦截
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取目标对象
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
// 获取通知器链
List
其实,有点分不清Spring 中Advice和Advisor的概念;
接下来分析一下:
5.1 切点和切面
Spring AOP中包含5中增强或者说通知:
有选择地织入到目标类某些特定的方法中,就需要使用切点进行目标连接点的定位,描述连接点;
Advice(org.aopalliance.aop.Advice接口):描述了增强的位置,方法前、后等;
PointCut(org.springframework.aop.Pointcut接口):描述了具体的哪些类、哪些方法上;Pointcut由ClassFilter和MethodMatcher构成;
public interface Pointcut { Pointcut TRUE = TruePointcut.INSTANCE; // 类过滤器,定位到特定的类上 ClassFilter getClassFilter(); // 方法匹配器,定位到特定的方法上 MethodMatcher getMethodMatcher(); }
Spring 提供6中切点类型:
切面由切点(pointcut)和增强(advice)组成,而advice中包含了增强的横切代码,pointcut包含了连接点的描述信息;
其实Spring中提供的增强MethodBeforeAdvice、AfterReturningAdvice等,也包含了连接点信息,就是一个切面,最终都会被AdvisorRegister转换成Advisor;
所以说,Spring 中的Advisor就是横切面的抽象,包含切点和增强;
Spring中的切面类型:
多个Advisor通过org.springframework.core.Ordered接口,来确定增强的顺序;
5.2 Spring 自动代理机制
之前,是通过ProxyFactoryBean,生成targetClass的代理对象,从容器中获取使用,但是对于众多bean需要代理的情况下,就需要Spring的自动代理机制了。
Spring通过org.springframework.beans.factory.config.BeanPostProcessor自动地完成这项工作。其实现类有3种:
5.3 日常用Spring AOP
两种方式:
1.XML配置:aop标签;
2.注解方式:需要aspectjrt.jar,aspectjweaver.jar提供的AspectJ注解;