上一篇博客寫了Spring IOC相關的內容,Spring的IOC實現原理源碼解析 ,希望可以先看完IOC的相關原理,再看AOP的文章,因爲Spring的AOP是建立在IOC的基礎之上的。本文主要了解以下內容:
(1)怎樣獲取增強器,在這裏,也就是通知方法
(2)怎樣創建代理對象
至於代理對象的調用方法的過程,可以參考 spring註解開發(四、AOP之目標方法的執行過程),這裏就不細說了。
本文的示例代碼,使用的是 Spring入門(四)之AOP 的代碼,感興趣的可以自行下載使用。
在IOC的基礎之上,我就直接跳過不太重要的內容了。
代理對象,是對原有對象的增強,所以肯定是在創建了原有的之後才創建代理對象的。
來到 AbstractAutowireCapableBeanFactory的initializeBean()方法:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//在bean初始化之前:執行xxAware接口的回調方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//在bean初始化之前:執行BeanPostProcessors的回調方法postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//執行bean的初始化方法:init-method方法,以及InitializingBean接口的回調方法afterPropertiesSet()
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//在bean初始化之前:執行BeanPostProcessors的回調方法postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
我們把目光轉移到初始化方法執行之後的後置處理邏輯:
//在bean初始化之前:執行BeanPostProcessors的回調方法postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
當BeanPostProcessor爲AspectJAwareAdvisorAutoProxyCreator時,會調用AbstractAutoProxyCreator的postProcessAfterInitialization()方法,創建代理對象:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//包裝對象,如果需要的話,其實就是返回代理對象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
我們的關注點是這句,對原有對象的包裝:
//包裝對象,如果需要的話,其實就是返回代理對象
return wrapIfNecessary(bean, beanName, cacheKey);
看看它具體是怎樣執行的:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 根據類型和beanName查找Advice和Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果存在相應的Advice、Advisor,就創建代理對象,並返回
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//創建代理對象!!!
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
到這裏,可以分爲兩大步了:
(1)根據類型和beanName查找Advice和Advisor
(2)如果存在相應的Advice、Advisor,就創建代理對象,並返回
一個個看吧:
一、根據類型和beanName查找Advice和Advisor
// 根據類型和beanName查找Advice和Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
調用的是AbstractAdvisorAutoProxyCreator的方法:
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//關注這句:獲取滿足條件的增強器
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
到了這裏,就要看看,它是怎樣獲取到滿足條件的增強器的:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//獲取所有的候選增強器,這個其實是通過循環getBean(name, Advisor.class)來獲取的
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//篩選出可以應用在目標類目標方法的增強器,這個是重點
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
對findAdvisorsThatCanApply()方法進行跟蹤,獲取能夠應用的增強器:
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//關注點在這裏,通過Aop工具來查找能夠應用的增強器
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
這裏,就會使用Aop的工具類來進行查找和匹配了,所以看看AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)方法:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
//如果候選的增強器爲空,則直接返回
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
//遍歷候選的增強器
for (Advisor candidate : candidateAdvisors) {
//如果是IntroductionAdvisor類型的,並且能夠應用到目標類
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
//則添加到返回列表
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
canApply方法有很多重載的方法,我跟到了這個:
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
崩潰了,這麼多重載的方法,有點長,我看了一下,後面會根據切入點表達式進行匹配,有點小複雜,這裏就不再跟進去了。
二、創建代理對象
回到AbstractAutoProxyCreator的wrapIfNecessary()方法:
//創建代理對象!!!
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
來到了這裏:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//將所有的通知適配爲Advisor類型
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//將增強器設置到代理工廠
proxyFactory.addAdvisors(advisors);
//設置目標對象
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//創建代理對象
return proxyFactory.getProxy(getProxyClassLoader());
}
到了這裏,又有兩個分支了:
(1)適配通知爲Advisor。
(2)創建代理對象
1.適配通知爲Advisor
來到AbstractAutoProxyCreator的buildAdvisors方法:
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
//將每個Advice對象適配成Advisor對象
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
看看是如何適配的:
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果是Advisor類型的,就直接強轉返回
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
//如果不是Advice類型的,就拋出異常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
//如果是MethodInterceptor類型的,則不需要適配器,直接返回DefaultPointcutAdvisor對象
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
//查找合適的適配器,適配後返回DefaultPointcutAdvisor對象
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
2.創建代理對象
來到ProxyFactory:
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
(1)先看createAopProxy()
cglib代理類,怎樣創建,就不是本文的重點了,只貼了一點相關的代碼。
會調用ProxyCreatorSupport的方法:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
其中getAopProxyFactory() 會返回一個DefaultAopProxyFactory對象
所以接下來會調用DefaultAopProxyFactory對象的createAopProxy()方法:
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.");
}
//如果目標對象是接口,或者是代理類,就使用JDK動態代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//否則,使用Cglib代理,示例代碼沒有實現接口,所以用的是Cglib代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
本示例代碼會走Cglib代理,所以最後返回的是Cglib代理對象。
(2)再看getProxy(classLoader);
所以調用的是CglibAopProxy的方法:
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
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();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 這裏就是創建代理對象了
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
來到了ObjenesisCglibAopProxy的方法:
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}
catch (Throwable ex) {
logger.debug("Unable to instantiate proxy using Objenesis, " +
"falling back to regular proxy construction", ex);
}
}
if (proxyInstance == null) {
// Regular instantiation via default constructor...
try {
Constructor<?> ctor = (this.constructorArgs != null ?
proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
proxyClass.getDeclaredConstructor());
ReflectionUtils.makeAccessible(ctor);
proxyInstance = (this.constructorArgs != null ?
ctor.newInstance(this.constructorArgs) : ctor.newInstance());
}
catch (Throwable ex) {
throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
"and regular proxy instantiation via default constructor fails as well", ex);
}
}
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}