标签:oss center fan lsa ref specific 注入 struct text
前面简单介绍了beanFactory提供的ioc,我们都知道spring使用jdk的动态代理实现了aop,这篇就来看看spring中的aop到底是怎么回事。
前面有提到,在beanFactory中,getBean会走到AbstractAutowireCapableBeanFactory中的doCreateBean,doCreateBean有如下代码段,populateBean主要是xml注入,initializeBean是初始化,产生aop的逻辑就在initializeBean中。
beanFactory就如同它的名字一样,只适合ID,测试AOP这里使用ClassPathXmlApplicationContext。
Feature | BeanFactory | ApplicationContext |
---|---|---|
Bean instantiation/wiring |
Yes |
Yes |
Automatic |
No |
Yes |
Automatic |
No |
Yes |
Convenient |
No |
Yes |
|
No |
Yes |
1 populateBean(beanName, mbd, instanceWrapper); 2 if (exposedObject != null) { 3 exposedObject = initializeBean(beanName, exposedObject, mbd); 4 }
initializeBean会调用applyBeanPostProcessorsAfterInitialization
1 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 2 throws BeansException { 3 4 Object result = existingBean; 5 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { 6 result = beanProcessor.postProcessAfterInitialization(result, beanName); 7 if (result == null) { 8 return result; 9 } 10 } 11 return result; 12 }
我们这里只关注和AOP相关的BeanPostProcessor,即org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator,InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization调用的是AbstractAutoProxyCreator的postProcessAfterInitialization,postProcessAfterInitialization又会调用wrapIfNecessary。
1 //有删减 2 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 3 // Create proxy if we have advice. 4 //得到所有候选Advisor,对Advisors和bean的方法双层遍历匹配,最终得到一个List<Advisor>,即specificInterceptors 5 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); 6 if (specificInterceptors != DO_NOT_PROXY) { 7 this.advisedBeans.put(cacheKey, Boolean.TRUE); 8 //重点方法 9 Object proxy = createProxy( 10 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); 11 this.proxyTypes.put(cacheKey, proxy.getClass()); 12 return proxy; 13 } 14 }
1 //AbstractAutoProxyCreator的createProxy,有删减 2 protected Object createProxy( 3 Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { 4 5 ProxyFactory proxyFactory = new ProxyFactory(); 6 //Copy configuration from the other config object. 7 proxyFactory.copyFrom(this); 8 9 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); 10 for (Advisor advisor : advisors) { 11 proxyFactory.addAdvisor(advisor); 12 } 13 //通过targetSource可以得到动态代理的target 14 proxyFactory.setTargetSource(targetSource); 15 //getProxy调用了createAopProxy().getProxy(classLoader),proxyFactory.createAopProxy()创建的是JdkDynamicAopProxy 16 return proxyFactory.getProxy(getProxyClassLoader()); 17 }
1 public Object getProxy(ClassLoader classLoader) { 2 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); 3 findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); 4 //jdk的动态代理,因为getProxy的调用者为JdkDynamicAopProxy,所以这里的InvocationHandler就为JdkDynamicAopProxy,最终注册的也是代理bean,target被雪藏 5 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 6 }
1 //JdkDynamicAopProxy的invoke方法,有删减 2 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 3 MethodInvocation invocation; 4 Object oldProxy = null; 5 boolean setProxyContext = false; 6 7 TargetSource targetSource = this.advised.targetSource; 8 Class<?> targetClass = null; 9 Object target = null; 10 11 Object retVal; 12 13 // May be null. Get as late as possible to minimize the time we "own" the target, 14 // in case it comes from a pool. 15 target = targetSource.getTarget(); 16 if (target != null) { 17 targetClass = target.getClass(); 18 } 19 20 // Get the interception chain for this method. 21 //组装拦截链 22 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 23 24 // Check whether we have any advice. If we don‘t, we can fallback on direct 25 // reflective invocation of the target, and avoid creating a MethodInvocation. 26 if (chain.isEmpty()) { 27 // We can skip creating a MethodInvocation: just invoke the target directly 28 // Note that the final invoker must be an InvokerInterceptor so we know it does 29 // nothing but a reflective operation on the target, and no hot swapping or fancy proxying. 30 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); 31 //通过反射直接调用target的方法 32 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); 33 } 34 else { 35 // We need to create a method invocation... 36 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); 37 // Proceed to the joinpoint through the interceptor chain. 38 //走拦截链 39 retVal = invocation.proceed(); 40 } 41 //return this时,返回proxy,而不是target 42 // Massage return value if necessary. 43 Class<?> returnType = method.getReturnType(); 44 if (retVal != null && retVal == target && 45 returnType != Object.class && returnType.isInstance(proxy) && 46 !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { 47 // Special case: it returned "this" and the return type of the method 48 // is type-compatible. Note that we can‘t help if the target sets 49 // a reference to itself in another returned object. 50 retVal = proxy; 51 } 52 53 return retVal; 54 55 }
标签:oss center fan lsa ref specific 注入 struct text
原文地址:http://www.cnblogs.com/holoyong/p/7367741.html