Bean第一次从容器获取的时候,如果bean配置了lookup-method,那么就使用了cglib来进行调用方法转换:
我们默认的容器DefaultListableBeanFactory,其中的getBean加载的时候会走到下面的代码:
org.springframework.beans.factory.support.SimpleInstantiationStrategy:
那么在通过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); } } }
<!-- Element : lookup-method A lookup method causes the IoC container to override the given method and return the bean with the name given in the bean attribute. This is a form of Method Injection. It is particularly useful as an alternative to implementing the BeanFactoryAware interface, in order to be able to make getBean() calls for non-singleton instances at runtime. In this case, Method Injection is a less invasive alternative. --> <bean class="..."> <lookup-method bean="" name=""/> </bean>
也就是配置了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()); } }