Bean第一次从容器获取的时候,如果bean配置了lookup-method,那么就使用了cglib来进行调用方法转换...

Bean第一次从容器获取的时候,如果bean配置了lookup-method,那么就使用了cglib来进行调用方法转换:


我们默认的容器DefaultListableBeanFactory,其中的getBean加载的时候会走到下面的代码:


org.springframework.beans.factory.support.SimpleInstantiationStrategy:

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. if (beanDefinition.getMethodOverrides().isEmpty()) { Constructor constructorToUse; synchronized (beanDefinition.constructorArgumentLock) { constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class clazz = beanDefinition.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction() { public Constructor run() throws Exception { return clazz.getDeclaredConstructor((Class[]) null); } }); } else { constructorToUse = clazz.getDeclaredConstructor((Class[]) null); } beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Exception ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. return instantiateWithMethodInjection(beanDefinition, beanName, owner); } }
那么在通过BeanDefinition创建Bean的时候,进行了beanDefinition.getMethodOverrides().isEmpty()判断,是通过cglib还是BeanUtils进行。
那么这个判断什么含义呢?
看我们dom树解析代码如下:
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate:
public static final String LOOKUP_METHOD_ELEMENT = "lookup-method"; public static final String REPLACED_METHOD_ELEMENT = "replaced-method"; /** * Parse lookup-override sub-elements of the given bean element. */ public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) { Element ele = (Element) node; String methodName = ele.getAttribute(NAME_ATTRIBUTE); String beanRef = ele.getAttribute(BEAN_ELEMENT); LookupOverride override = new LookupOverride(methodName, beanRef); override.setSource(extractSource(ele)); overrides.addOverride(override); } } }

也就是配置了lookup-method的时候用cglib,因为要借助cglib来替换方法。
具体的cglib的操作是通过filter判断来调用什么代理返回形式:

private class CallbackFilterImpl extends CglibIdentitySupport implements CallbackFilter { public int accept(Method method) { MethodOverride methodOverride = beanDefinition.getMethodOverrides().getOverride(method); if (logger.isTraceEnabled()) { logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]"); } if (methodOverride == null) { return PASSTHROUGH; } else if (methodOverride instanceof LookupOverride) { return LOOKUP_OVERRIDE; } else if (methodOverride instanceof ReplaceOverride) { return METHOD_REPLACER; } throw new UnsupportedOperationException( "Unexpected MethodOverride subclass: " + methodOverride.getClass().getName()); } }


你可能感兴趣的:(Bean第一次从容器获取的时候,如果bean配置了lookup-method,那么就使用了cglib来进行调用方法转换...)