《Spring技术内幕》学习笔记8——创建AOP代理对象并对目标对象切面拦截
2017-10-12 11:31
489 查看
原文链接http://blog.csdn.net/chjttony/article/details/6311979
1.Spring AOP的底层实现常用类:
分析Spring AOP的底层实现首先要从ProxyConfig类开始,ProxyConfig是所有产生Spring
AOP代理对象的基类,它是一个数据类,主要为其AOP代理对象工厂实现类提供配置属性。根据ProxyConfig的继承体系分析创建AOP代理常用类的作用:
(1).AdvisedSupport是ProxyConfig的子类,它封装了AOP中对通知(Advice)和通知器(Advisor)的相关操作,这些操作对于不同的AOP的代理对象的生成都是一样的,但对于具体的AOP代理对象的创建,AdvisedSupport把它交给子类去实现。
(2).ProxyCreatorSupport是AdvisedSupport的子类,它是其子类创建AOP代理对象的一个辅助类,提供不同AOP代理对象生成的通用操作,具体的AOP代理对象生成,由ProxyCreatorSupport的子类完成。
(3).创建AOP代理对象的类:
ProxyCreatorSupport有3个子类,分别创建不同的AOP代理对象,具体如下:
a.AspectJProxyFactory:主要用于创建AspectJ的AOP应用,起到集成Spring和AspectJ的作用。
b.ProxyFactory:创建编程式的Spring AOP应用。
c.ProxyFactoryBean:创建声明式的Spring AOP应用。
2.声明式Spring AOP代理工厂对象ProxyFactoryBean:
我们以ProxyFactoryBean为例,分析Spring AOP的实现原理,ProxyFactoryBean是Spring中一个非常灵活的创建AOP应用的底层方法,封装了AOP的主要功能。
一个简单的AOP代理工厂对象的配置如下:
[xhtml] view plain copy
<!--配置通知器,通知器的实现定义了需要对目标对象进行的增强行为-->
<bean id=”testAdvisor” class=”com.test.TestAdvisor”/>
<!--配置AOP代理,封装AOP功能的主要类-->
<bean id=”testAOP” class=”org.springframework.aop.ProxyFactoryBean”>
<!--AOP代理接口-->
<property name=”proxyInterfaces”>
<value>com.test.TestProxyInterface</value>
</property>
<!--需要使用AOP切面增强的对象-->
<property name=”target”>
<bean class=”com.test.TestTarget”/>
</property>
<!--代理拦截器,配置通知器的名称,即通知器在AOP代理的配置下通过使用代理对象的拦截机制发挥作用-->
<property name=”interceptorNames”>
<list>
<value>testAdvisor</value>
</list>
</property>
</bean>
3.ProxyFactoryBean生成AOPProxy代理对象:
从2中ProxyFactoryBean的简单配置例子我们可以看出,ProxyFactoryBean是用来配置目标对象和切面行为Advice的,ProxyFactoryBean通过其配置的拦截器名称interceptorNames即通知器Advisor将切面行为Advice应用到目标对象中。
在ProxyFactoryBean中,需要为待增强目标对象目标对象生成Proxy代理对象,从而为AOP切面的编织提供基础,下面通过源码分析ProxyFactoryBean的生成AOPProxy代理对象的实现过程:
(1).ProxyFactoryBean产生代理对象的主要源码:
[java] view plain copy
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
//标注通知器器为全局通用通知器
public static final String GLOBAL_SUFFIX = "*";
//标志通知器链是否已经完成初始化
private boolean advisorChainInitialized = false;
//单态模式对象
private Object singletonInstance;
……
//ProxyFactoryBean创建AOPProxy代理的入口方法
public Object getObject() throws BeansException {
//初始化通知器链
initializeAdvisorChain();
//如果目标对象是单态模式
if (isSingleton()) {
//调用获取单态模式对象的方法产生AOPProxy代理
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.");
}
//调用原型模式对象方法每次创建一个新的AOPProxy代理对象
return newPrototypeInstance();
}
}
//初始化通知器链
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
//如果通知器链已经被初始化,则直接返回,即通知器链只在第一次获取代理对象时产生
if (this.advisorChainInitialized) {
return;
}
//如果ProxyFactoryBean中配置的连接器列名名称不为空
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)) {
//从容器获取单态模式的通知或者通知器
advice = this.beanFactory.getBean(name);
}
//如果通知器是原型模式
else {
//创建一个新的通知或者通知器对象
advice = new PrototypePlaceholderAdvisor(name);
}
//添加通知器
addAdvisorOnChainCreation(advice, name);
}
}
}
//设置通知器链已初始化标识
this.advisorChainInitialized = true;
}
//获取一个单态模式的AOPProxy代理对象
private synchronized Object getSingletonInstance() {
//如果单态模式的代理对象还未被创建
if (this.singletonInstance == null) {
//获取代理的目标源
this.targetSource = freshTargetSource();
//如果ProxyFactoryBean设置了自动探测接口属性,并且没有配置代理接
//且不是目标对象的直接代理类
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));
}
//初始化共享的单态模式对象 super.setFrozen(this.freezeProxy);
//调用ProxyFactory生成代理AOPProxy对象
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
//获取一个原型模式的代理对象
private synchronized Object newPrototypeInstance() {
if (logger.isTraceEnabled()) {
logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
}
//根据当前的AOPProxyFactory获取一个创建代理的辅助类
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
//获取一个刷新的目标源
TargetSource targetSource = freshTargetSource();
//从当前对象中拷贝AOP的配置,为了保持原型模式对象的独立性,每次创建代理
//对象时都需要拷贝AOP的配置,以保证原型模式AOPProxy代理对象的独立性
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);
}
//调用ProxyFactory生成AOPProxy代理
return getProxy(copy.createAopProxy());
}
//使用createAopProxy方法返回的AOPProxy对象产生AOPProxy代理对象
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
……
}
通过源码分析,我们了解到AOPProxyFactory实现了FactoryBean接口,所以本身也是一个Spring的工厂Bean,AOP代理工厂的主要功能概况为:
a.初始化通知器链,将配置的通知器链添加到容器存放通知/通知器的集合中。
b.根据单态模式/原型模式,获取AOPProxy产生AOPProxy代理对象。
(2).AOP创建辅助器(AOPCreatorSupport)获取AOPProxy代理对象:
AOPProxyFactory的getSingletonInstance和newPrototypeInstance方法均通过调用AOPCreatorSupport的createAopProxy()方法获取AOPProxy,主要源码如下:
[java] view plain copy
public class ProxyCreatorSupport extends AdvisedSupport {
//AOPProxy工厂
private AopProxyFactory aopProxyFactory;
//当第一个AOPProxy代理对象被创建时,设置为true
private boolean active = false;
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
//默认使用DefaultAopProxyFactory作用AOP代理工厂
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
//创建AOPProxy代理的入口方法
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//调用DefaultAopProxyFactory的创建AOPProxy代理的方法
return getAopProxyFactory().createAopProxy(this);
}
//激活AOP代理配置,向容器注册代理回调监听器,第一次创建AOP代理时调用
private void activate() {
this.active = true;
for (AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
……
}
通过对ProxyCreatorSupport的源码分析,我们知道真正创建AOPProxy代理对象的是DefaultAopProxyFactory类。
(3).DefaultAopProxyFactory创建AOPProxy代理对象:
DefaultAopProxyFactory是AOP创建辅助器(AOPCreatorSupport)默认的AOP代理工厂,DefaultAopProxyFactory的createAopProxy方法实现了创建AOP代理的功能,源码如下:
[java] view plain copy
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
//判断CGLIB类库是否在classpath中
private static final boolean cglibAvailable =
ClassUtils.isPresent("net.sf.cglib.proxy.Enhancer", DefaultAopProxyFactory.class.getClassLoader());
//创建AOP代理对象
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//如果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动态代理机制来生成AOP代理
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
//如果AOP配置的目标类不是接口,则使用CGLIB的方式来生成AOP代理
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. " +
"Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
//判断AOP是否只配置了SpringProxy代理接口或者没有配置任何代理接口
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
//获取AOP配置的所有AOP代理接口
Class[] interfaces = config.getProxiedInterfaces();
return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
}
}
通过对DefaultAopProxyFactory的源码分析,我们了解了Spring在创建AOP代理对象时,如果配置的目标类是接口,则使用JDK的动态代理机制来生成AOP代理,如果使用的不是接口,则使用CGLIB方式来生成AOP的动态代理。
4.JDK动态代理机制创建AOPProxy代理对象:
JDK的动态代理机制只能对接口起作用,即如果要对一个对象使用JDK动态代理方式生成代理对象时,该对象必须实现接口,Spring中通过JdkDynamicAopProxy类使用JDK动态代理机制生成AOPProxy代理对象,JdkDynamicAopProxy的主要源码如下:
[java] view plain copy
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
……
//JdkDynamicAopProxy的构造方法
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
//获取AOPBeanFactory中配置的通知器链和目标源
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());
}
//获取AOPBeanFactory中配置的代理接口
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
//查找代理目标的接口中是否定义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) {
//如果方法是equals()方法,则设置当前对象equalsDefined属性
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
//如果方法是hashCode()方法,则设置当前对象hashCodeDefined属性
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
//AOP代理对象的回调方法
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()方法,即目标对象没有自己实现equals()方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
//如果代理目标对象的接口中没有定义hashCode()方法,且当前调用的方法
//是hashCode()方法,即目标对象没有自己实现hashCode()方法
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
//如果AOP配置了通知,使用反射机制调用通知的同名方法
if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//如果当前通知暴露了代理,则将当前代理使用currentProxy()方法变为可用代理
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取目标对象
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
//获取目标对象方法配置的拦截器(通知器)链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果没有配置任何通知
if (chain.isEmpty()) {
//没有配置通知,使用反射直接调用目标对象的方法,并获取方法返回值
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
//如果配置了通知
else {
//为目标对象创建方法回调对象,需要在调用通知之后才调用目标对象的方法
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//调用通知链,沿着通知器链调用所有配置的通知
retVal = invocation.proceed();
}
//如果方法有返回值,则将代理对象最为方法返回
if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
//释放目标对象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
//存储代理对象
AopContext.setCurrentProxy(oldProxy);
}
}
}
……
}
通过上述源码分析,我们看到JdkDynamicAopProxy本身实现了InvocationHandler接口和invoke()方法,JDK的动态代理机制的工作原理是:当调用目标对象的方法时,不是直接调用目标对象,而是首先生成一个目标对象的动态代理对象,触发代理对象的invoke()方法,代理的invoke()方法才会真正调用目标对象的方法。Spring
AOP的实现原理是在代理对象invoke()方法调用目标对象的方法时,调用配置的通知。
5.CglibProxyFactory创建AOPProxy代理:
JDK的动态代理只能针对接口生成代理对象,对于没有实现接口的目标对象,必须通过第3方的CGLIB来生成代理对象,CglibProxyFactory创建AOPProxy代理的主要源码如下:
[java] view plain copy
//通过CGLIB方式创建AOP代理对象
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.getTargetSource());
}
try {
//从代理创建辅助类中获取在IoC容器中配置的目标对象
Class rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
//将目标对象本身做为自己的基类
Class proxySuperClass = rootClass;
//检查获取到的目标类是否是CGLIB产生的
if (AopUtils.isCglibProxyClass(rootClass)) {
//如果目标类是有CGLIB产生的,获取目标类的基类
proxySuperClass = rootClass.getSuperclass();
//获取目标类的接口
Class[] additionalInterfaces = rootClass.getInterfaces();
//将目标类的接口添加到容器AOP代理创建辅助类的配置中
for (Class additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
//校验代理基类
validateClassIfNecessary(proxySuperClass);
//配置CGLIB的Enhancer类,Enhancer是CGLIB中的主要操作类
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
//设置enhancer的基类
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
//设置enhancer的接口 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setInterceptDuringConstruction(false);
//设置enhancer的回调方法
Callback[] callbacks = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
//将通知器中配置作为enhancer的方法过滤
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
Class[] types = new Class[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
//设置enhancer的回调类型
enhancer.setCallbackTypes(types);
//创建代理对象
Object proxy;
if (this.constructorArgs != null) {
proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
}
else {
proxy = enhancer.create();
}
return proxy;
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Exception ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
//获取给定类的回调通知
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, //普通通知
targetInterceptor, // 如果优化则不考虑配置的通知
new SerializableNoOp(), //没有被覆盖的方法
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<String, Integer>(methods.length);
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
//将固定回调和主要回调拷贝到回调数组中
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
//如果目标不是静态的,或者通知链不被冻结,则使用AOP主要的通知
else {
callbacks = mainCallbacks;
}
return callbacks;
}
通过上面对CGLIB创建代理和获取回答通知的源码分析,我们了解到CGLIB在获取代理的通知时,会创建DynamicAdvisedInterceptor类,当应用调用目标对象的方法时,不是直接调用目标对象,而是通过CGLIB创建的代理对象来调用目标对象,在调用目标对象的方法时,触发DynamicAdvisedInterceptor的intercept回调方法对目标对象进行处理,CGLIB回调拦截器链的源码如下:
[java] view plain copy
//CGLIB回调AOP拦截器链
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();
}
//获取AOP配置的通知
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
//如果没有配置通知
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
//直接调用目标对象的方法
retVal = methodProxy.invoke(target, args);
}
//如果配置了通知
else {
//通过CglibMethodInvocation来启动配置的通知
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
//获取目标对象对象方法的回调结果,如果有必要则封装为代理
retVal = massageReturnTypeIfNecessary(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
//存储被回调的代理
AopContext.setCurrentProxy(oldProxy);
}
}
}
6.目标对象方法的调用:
通过上面4和5分别对JdkDynamicAopProxy和Cglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们可以看出,当目标对象没有配置通知器时,代理对象直接调用目标对象的方法,下面具体分析直接调用目标对象方法的过程:
(1).JdkDynamicAopProxy直接调用目标对象方法:
JdkDynamicAopProxy中是通过AopUtils.invokeJoinpointUsingReflection方法来直接调用目标对象的方法,源码如下:
[java] view plain copy
//通过反射机制直接调用目标对象方法
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {
try {
//通过反射使给定的方法可以访问,主要是对protected和private方法使用,//取消严格访问控制权限的限制
ReflectionUtils.makeAccessible(method);
//使用反射机制调用目标对象的方法
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
(2).Cglib2AopProxy直接调用目标对象方法:
Cglib2AopProxy是通过methodProxy.invoke来直接调用目标对象的方法,主要源码如下:
[java] view plain copy
retVal = methodProxy.invoke(target, args);
methodProxy是CGLIB中MethodProxy类的对象,因为我对CGLIB也不熟悉,这里不做深入了解。
7.AOP拦截器链的调用:
通过上面4和5分别对JdkDynamicAopProxy和Cglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们了解到,当目标对象配置了通知器时,在对目标对象方法调用前首先需要回调通知器链,JdkDynamicAopProxy和Cglib2AopProxy都是通过将目标对象方法、方法参数、和通知器链、代理对象等封装为ReflectiveMethodInvocation类,然后通过ReflectiveMethodInvocation.proceed()方法调用通知器链,proceed方法源码如下:
[java] view plain copy
//通用通知器链
public Object proceed() throws Throwable {
//如果拦截器链中通知已经调用完毕
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//这个方法调用AopUtils.invokeJoinpointUsingReflection方法,
//通过反射机制直接调用目标对象方法
return invokeJoinpoint();
}
//获取拦截器链中的通知器或通知
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果获取的通知器或通知是动态匹配方法拦截器类型
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
//动态匹配方法拦截器
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
//如果匹配,调用拦截器的方法
return dm.interceptor.invoke(this);
}
else {
//如果不匹配,递归调用proceed()方法,知道拦截器链被全部调用为止
return proceed();
}
}
else {
//如果不是动态匹配方法拦截器,则切入点在构造对象之前进行静态匹配,调用
//拦截器的方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
1.Spring AOP的底层实现常用类:
分析Spring AOP的底层实现首先要从ProxyConfig类开始,ProxyConfig是所有产生Spring
AOP代理对象的基类,它是一个数据类,主要为其AOP代理对象工厂实现类提供配置属性。根据ProxyConfig的继承体系分析创建AOP代理常用类的作用:
(1).AdvisedSupport是ProxyConfig的子类,它封装了AOP中对通知(Advice)和通知器(Advisor)的相关操作,这些操作对于不同的AOP的代理对象的生成都是一样的,但对于具体的AOP代理对象的创建,AdvisedSupport把它交给子类去实现。
(2).ProxyCreatorSupport是AdvisedSupport的子类,它是其子类创建AOP代理对象的一个辅助类,提供不同AOP代理对象生成的通用操作,具体的AOP代理对象生成,由ProxyCreatorSupport的子类完成。
(3).创建AOP代理对象的类:
ProxyCreatorSupport有3个子类,分别创建不同的AOP代理对象,具体如下:
a.AspectJProxyFactory:主要用于创建AspectJ的AOP应用,起到集成Spring和AspectJ的作用。
b.ProxyFactory:创建编程式的Spring AOP应用。
c.ProxyFactoryBean:创建声明式的Spring AOP应用。
2.声明式Spring AOP代理工厂对象ProxyFactoryBean:
我们以ProxyFactoryBean为例,分析Spring AOP的实现原理,ProxyFactoryBean是Spring中一个非常灵活的创建AOP应用的底层方法,封装了AOP的主要功能。
一个简单的AOP代理工厂对象的配置如下:
[xhtml] view plain copy
<!--配置通知器,通知器的实现定义了需要对目标对象进行的增强行为-->
<bean id=”testAdvisor” class=”com.test.TestAdvisor”/>
<!--配置AOP代理,封装AOP功能的主要类-->
<bean id=”testAOP” class=”org.springframework.aop.ProxyFactoryBean”>
<!--AOP代理接口-->
<property name=”proxyInterfaces”>
<value>com.test.TestProxyInterface</value>
</property>
<!--需要使用AOP切面增强的对象-->
<property name=”target”>
<bean class=”com.test.TestTarget”/>
</property>
<!--代理拦截器,配置通知器的名称,即通知器在AOP代理的配置下通过使用代理对象的拦截机制发挥作用-->
<property name=”interceptorNames”>
<list>
<value>testAdvisor</value>
</list>
</property>
</bean>
3.ProxyFactoryBean生成AOPProxy代理对象:
从2中ProxyFactoryBean的简单配置例子我们可以看出,ProxyFactoryBean是用来配置目标对象和切面行为Advice的,ProxyFactoryBean通过其配置的拦截器名称interceptorNames即通知器Advisor将切面行为Advice应用到目标对象中。
在ProxyFactoryBean中,需要为待增强目标对象目标对象生成Proxy代理对象,从而为AOP切面的编织提供基础,下面通过源码分析ProxyFactoryBean的生成AOPProxy代理对象的实现过程:
(1).ProxyFactoryBean产生代理对象的主要源码:
[java] view plain copy
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
//标注通知器器为全局通用通知器
public static final String GLOBAL_SUFFIX = "*";
//标志通知器链是否已经完成初始化
private boolean advisorChainInitialized = false;
//单态模式对象
private Object singletonInstance;
……
//ProxyFactoryBean创建AOPProxy代理的入口方法
public Object getObject() throws BeansException {
//初始化通知器链
initializeAdvisorChain();
//如果目标对象是单态模式
if (isSingleton()) {
//调用获取单态模式对象的方法产生AOPProxy代理
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.");
}
//调用原型模式对象方法每次创建一个新的AOPProxy代理对象
return newPrototypeInstance();
}
}
//初始化通知器链
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
//如果通知器链已经被初始化,则直接返回,即通知器链只在第一次获取代理对象时产生
if (this.advisorChainInitialized) {
return;
}
//如果ProxyFactoryBean中配置的连接器列名名称不为空
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)) {
//从容器获取单态模式的通知或者通知器
advice = this.beanFactory.getBean(name);
}
//如果通知器是原型模式
else {
//创建一个新的通知或者通知器对象
advice = new PrototypePlaceholderAdvisor(name);
}
//添加通知器
addAdvisorOnChainCreation(advice, name);
}
}
}
//设置通知器链已初始化标识
this.advisorChainInitialized = true;
}
//获取一个单态模式的AOPProxy代理对象
private synchronized Object getSingletonInstance() {
//如果单态模式的代理对象还未被创建
if (this.singletonInstance == null) {
//获取代理的目标源
this.targetSource = freshTargetSource();
//如果ProxyFactoryBean设置了自动探测接口属性,并且没有配置代理接
//且不是目标对象的直接代理类
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));
}
//初始化共享的单态模式对象 super.setFrozen(this.freezeProxy);
//调用ProxyFactory生成代理AOPProxy对象
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
//获取一个原型模式的代理对象
private synchronized Object newPrototypeInstance() {
if (logger.isTraceEnabled()) {
logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
}
//根据当前的AOPProxyFactory获取一个创建代理的辅助类
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
//获取一个刷新的目标源
TargetSource targetSource = freshTargetSource();
//从当前对象中拷贝AOP的配置,为了保持原型模式对象的独立性,每次创建代理
//对象时都需要拷贝AOP的配置,以保证原型模式AOPProxy代理对象的独立性
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);
}
//调用ProxyFactory生成AOPProxy代理
return getProxy(copy.createAopProxy());
}
//使用createAopProxy方法返回的AOPProxy对象产生AOPProxy代理对象
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
……
}
通过源码分析,我们了解到AOPProxyFactory实现了FactoryBean接口,所以本身也是一个Spring的工厂Bean,AOP代理工厂的主要功能概况为:
a.初始化通知器链,将配置的通知器链添加到容器存放通知/通知器的集合中。
b.根据单态模式/原型模式,获取AOPProxy产生AOPProxy代理对象。
(2).AOP创建辅助器(AOPCreatorSupport)获取AOPProxy代理对象:
AOPProxyFactory的getSingletonInstance和newPrototypeInstance方法均通过调用AOPCreatorSupport的createAopProxy()方法获取AOPProxy,主要源码如下:
[java] view plain copy
public class ProxyCreatorSupport extends AdvisedSupport {
//AOPProxy工厂
private AopProxyFactory aopProxyFactory;
//当第一个AOPProxy代理对象被创建时,设置为true
private boolean active = false;
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
//默认使用DefaultAopProxyFactory作用AOP代理工厂
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
//创建AOPProxy代理的入口方法
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//调用DefaultAopProxyFactory的创建AOPProxy代理的方法
return getAopProxyFactory().createAopProxy(this);
}
//激活AOP代理配置,向容器注册代理回调监听器,第一次创建AOP代理时调用
private void activate() {
this.active = true;
for (AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
……
}
通过对ProxyCreatorSupport的源码分析,我们知道真正创建AOPProxy代理对象的是DefaultAopProxyFactory类。
(3).DefaultAopProxyFactory创建AOPProxy代理对象:
DefaultAopProxyFactory是AOP创建辅助器(AOPCreatorSupport)默认的AOP代理工厂,DefaultAopProxyFactory的createAopProxy方法实现了创建AOP代理的功能,源码如下:
[java] view plain copy
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
//判断CGLIB类库是否在classpath中
private static final boolean cglibAvailable =
ClassUtils.isPresent("net.sf.cglib.proxy.Enhancer", DefaultAopProxyFactory.class.getClassLoader());
//创建AOP代理对象
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//如果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动态代理机制来生成AOP代理
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
//如果AOP配置的目标类不是接口,则使用CGLIB的方式来生成AOP代理
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. " +
"Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
//判断AOP是否只配置了SpringProxy代理接口或者没有配置任何代理接口
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
//获取AOP配置的所有AOP代理接口
Class[] interfaces = config.getProxiedInterfaces();
return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
}
}
通过对DefaultAopProxyFactory的源码分析,我们了解了Spring在创建AOP代理对象时,如果配置的目标类是接口,则使用JDK的动态代理机制来生成AOP代理,如果使用的不是接口,则使用CGLIB方式来生成AOP的动态代理。
4.JDK动态代理机制创建AOPProxy代理对象:
JDK的动态代理机制只能对接口起作用,即如果要对一个对象使用JDK动态代理方式生成代理对象时,该对象必须实现接口,Spring中通过JdkDynamicAopProxy类使用JDK动态代理机制生成AOPProxy代理对象,JdkDynamicAopProxy的主要源码如下:
[java] view plain copy
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
……
//JdkDynamicAopProxy的构造方法
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
//获取AOPBeanFactory中配置的通知器链和目标源
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());
}
//获取AOPBeanFactory中配置的代理接口
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
//查找代理目标的接口中是否定义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) {
//如果方法是equals()方法,则设置当前对象equalsDefined属性
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
//如果方法是hashCode()方法,则设置当前对象hashCodeDefined属性
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
//AOP代理对象的回调方法
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()方法,即目标对象没有自己实现equals()方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
//如果代理目标对象的接口中没有定义hashCode()方法,且当前调用的方法
//是hashCode()方法,即目标对象没有自己实现hashCode()方法
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
//如果AOP配置了通知,使用反射机制调用通知的同名方法
if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//如果当前通知暴露了代理,则将当前代理使用currentProxy()方法变为可用代理
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取目标对象
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
//获取目标对象方法配置的拦截器(通知器)链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果没有配置任何通知
if (chain.isEmpty()) {
//没有配置通知,使用反射直接调用目标对象的方法,并获取方法返回值
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
//如果配置了通知
else {
//为目标对象创建方法回调对象,需要在调用通知之后才调用目标对象的方法
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//调用通知链,沿着通知器链调用所有配置的通知
retVal = invocation.proceed();
}
//如果方法有返回值,则将代理对象最为方法返回
if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
//释放目标对象
targetSource.releaseTarget(target);
}
if (setProxyContext) {
//存储代理对象
AopContext.setCurrentProxy(oldProxy);
}
}
}
……
}
通过上述源码分析,我们看到JdkDynamicAopProxy本身实现了InvocationHandler接口和invoke()方法,JDK的动态代理机制的工作原理是:当调用目标对象的方法时,不是直接调用目标对象,而是首先生成一个目标对象的动态代理对象,触发代理对象的invoke()方法,代理的invoke()方法才会真正调用目标对象的方法。Spring
AOP的实现原理是在代理对象invoke()方法调用目标对象的方法时,调用配置的通知。
5.CglibProxyFactory创建AOPProxy代理:
JDK的动态代理只能针对接口生成代理对象,对于没有实现接口的目标对象,必须通过第3方的CGLIB来生成代理对象,CglibProxyFactory创建AOPProxy代理的主要源码如下:
[java] view plain copy
//通过CGLIB方式创建AOP代理对象
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.getTargetSource());
}
try {
//从代理创建辅助类中获取在IoC容器中配置的目标对象
Class rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
//将目标对象本身做为自己的基类
Class proxySuperClass = rootClass;
//检查获取到的目标类是否是CGLIB产生的
if (AopUtils.isCglibProxyClass(rootClass)) {
//如果目标类是有CGLIB产生的,获取目标类的基类
proxySuperClass = rootClass.getSuperclass();
//获取目标类的接口
Class[] additionalInterfaces = rootClass.getInterfaces();
//将目标类的接口添加到容器AOP代理创建辅助类的配置中
for (Class additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
//校验代理基类
validateClassIfNecessary(proxySuperClass);
//配置CGLIB的Enhancer类,Enhancer是CGLIB中的主要操作类
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
//设置enhancer的基类
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
//设置enhancer的接口 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setInterceptDuringConstruction(false);
//设置enhancer的回调方法
Callback[] callbacks = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
//将通知器中配置作为enhancer的方法过滤
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
Class[] types = new Class[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
//设置enhancer的回调类型
enhancer.setCallbackTypes(types);
//创建代理对象
Object proxy;
if (this.constructorArgs != null) {
proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
}
else {
proxy = enhancer.create();
}
return proxy;
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Exception ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
//获取给定类的回调通知
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, //普通通知
targetInterceptor, // 如果优化则不考虑配置的通知
new SerializableNoOp(), //没有被覆盖的方法
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<String, Integer>(methods.length);
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
//将固定回调和主要回调拷贝到回调数组中
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
//如果目标不是静态的,或者通知链不被冻结,则使用AOP主要的通知
else {
callbacks = mainCallbacks;
}
return callbacks;
}
通过上面对CGLIB创建代理和获取回答通知的源码分析,我们了解到CGLIB在获取代理的通知时,会创建DynamicAdvisedInterceptor类,当应用调用目标对象的方法时,不是直接调用目标对象,而是通过CGLIB创建的代理对象来调用目标对象,在调用目标对象的方法时,触发DynamicAdvisedInterceptor的intercept回调方法对目标对象进行处理,CGLIB回调拦截器链的源码如下:
[java] view plain copy
//CGLIB回调AOP拦截器链
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();
}
//获取AOP配置的通知
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
//如果没有配置通知
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
//直接调用目标对象的方法
retVal = methodProxy.invoke(target, args);
}
//如果配置了通知
else {
//通过CglibMethodInvocation来启动配置的通知
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
//获取目标对象对象方法的回调结果,如果有必要则封装为代理
retVal = massageReturnTypeIfNecessary(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
//存储被回调的代理
AopContext.setCurrentProxy(oldProxy);
}
}
}
6.目标对象方法的调用:
通过上面4和5分别对JdkDynamicAopProxy和Cglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们可以看出,当目标对象没有配置通知器时,代理对象直接调用目标对象的方法,下面具体分析直接调用目标对象方法的过程:
(1).JdkDynamicAopProxy直接调用目标对象方法:
JdkDynamicAopProxy中是通过AopUtils.invokeJoinpointUsingReflection方法来直接调用目标对象的方法,源码如下:
[java] view plain copy
//通过反射机制直接调用目标对象方法
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {
try {
//通过反射使给定的方法可以访问,主要是对protected和private方法使用,//取消严格访问控制权限的限制
ReflectionUtils.makeAccessible(method);
//使用反射机制调用目标对象的方法
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
(2).Cglib2AopProxy直接调用目标对象方法:
Cglib2AopProxy是通过methodProxy.invoke来直接调用目标对象的方法,主要源码如下:
[java] view plain copy
retVal = methodProxy.invoke(target, args);
methodProxy是CGLIB中MethodProxy类的对象,因为我对CGLIB也不熟悉,这里不做深入了解。
7.AOP拦截器链的调用:
通过上面4和5分别对JdkDynamicAopProxy和Cglib2AopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们了解到,当目标对象配置了通知器时,在对目标对象方法调用前首先需要回调通知器链,JdkDynamicAopProxy和Cglib2AopProxy都是通过将目标对象方法、方法参数、和通知器链、代理对象等封装为ReflectiveMethodInvocation类,然后通过ReflectiveMethodInvocation.proceed()方法调用通知器链,proceed方法源码如下:
[java] view plain copy
//通用通知器链
public Object proceed() throws Throwable {
//如果拦截器链中通知已经调用完毕
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//这个方法调用AopUtils.invokeJoinpointUsingReflection方法,
//通过反射机制直接调用目标对象方法
return invokeJoinpoint();
}
//获取拦截器链中的通知器或通知
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果获取的通知器或通知是动态匹配方法拦截器类型
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
//动态匹配方法拦截器
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
//如果匹配,调用拦截器的方法
return dm.interceptor.invoke(this);
}
else {
//如果不匹配,递归调用proceed()方法,知道拦截器链被全部调用为止
return proceed();
}
}
else {
//如果不是动态匹配方法拦截器,则切入点在构造对象之前进行静态匹配,调用
//拦截器的方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
相关文章推荐
- 《Spring技术内幕》学习笔记8——创建AOP代理对象并对目标对象切面拦截
- 《Spring技术内幕》学习笔记8——创建AOP代理对象并对目标对象切面拦截
- spring技术内幕8-创建AOP代理对象并对目标对象切面拦截
- AOP系列(二)——为符合条件的目标对象创建代理
- AOP实现拦截对象以及获取切入目标方法和注解
- Spring AOP 源码分析 - 创建代理对象
- Spring源码阅读4.2-Aspecjt AOP之代理对象的创建
- jdk与cglib动态代理目标对象创建对比
- AOP实现拦截对象以及获取切入目标方法和注解
- 黑马程序员--09.动态与代理AOP--06【动态代理实例化的过程升级--目标对象+系统功能的参数化】【实现类似Spring的可配置AOP框架】
- AOP实现拦截对象以及获取切入目标方法和注解
- AOP实现拦截对象以及获取切入目标方法和注解
- Spring3.1.0实现原理分析(十).AOP之代理对象执行拦截过程
- Spring AOP 源码分析——创建代理对象
- 【Spring源码--AOP的实现】(一)AopProxy代理对象的创建
- Spring 代理对象,cglib,jdk的问题思考,AOP 配置注解拦截 的一些问题.为什么不要注解在接口,以及抽象方法.
- spring生成代理对象的过程(AOP切面)
- AOP实现拦截对象以及获取切入目标方法和注解
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-使用工厂创建代理(Using the ProxyFactoryObject to create AOP proxies)
- AOP实现拦截对象以及获取切入目标方法和注解