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<Constructor>() {
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);
}
}
}
<!--
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());
}
}
分享到:
相关推荐
RevitLookup-2021.0.0.13,供各位做REVIT二次开发的同仁们下载、学习、研究。
revit开发必备工具 本包中是已经编译过的文件,可以直接使用 ...编辑其中RevitLookup.dll 路径为编译路径 C:\RevitLookup-2016.0.0.6\CS\bin\Debug\RevitLookup.dll 重启revit: 即可在菜单栏看到工具
RevitLookup-2017.0.0.5RevitLookup-2017.0.0.5RevitLookup-2017.0.0.5RevitLookup-2017.0.0.5RevitLookup-2017.0.0.5
Spring系列第12篇:lazy-init:bean延迟初始化Spring系列第13篇:使用继承简化bean配置(abstract & parent)Spring系列第14篇:lookup-method和replaced-method比较陌生,怎么玩的?Spring系列第15篇:代理详解(Java...
RevitLookup - 2016 的 源码,需要自己编译 用法:将RevitLookup.addin和RevitLookup.dll放到C:\ProgramData\Autodesk\Revit\Addins\2016下即可
RevitLookup - 2017 的 源码,需要自己编译 用法:将RevitLookup.addin和RevitLookup.dll放到C:\ProgramData\Autodesk\Revit\Addins\2017下即可
lookup-dns- dns.lookup替换dns.lookup标准方法的DNS缓存超级简单易用const request = require ( 'request' ) ;const { lookup } = require ( 'lookup-dns-cache' ) ;// With "request" modulerequest ( { url : '...
资源分类:Python库 所属语言:Python 使用前提:需要解压 资源全名:iso3_lookup-0.3.0-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
RevitLookup-2020.0.0.4 官方公布源代码需要自己编译,方便学习REVIT内核构架和开发
RevitLookup - 2018 的 源码,需要自己编译 用法:将RevitLookup.addin和RevitLookup.dll放到C:\ProgramData\Autodesk\Revit\Addins\2018下即可
前端开源库-nsq-lookup-jcnsq lookup jc,通过nsqlookupd查找nsqd实例
资源来自pypi官网。 资源全名:django_lookup_extensions-0.2.0-py2.py3-none-any.whl
lookup窗体
Revit二次开发必备插件,分享给没找到最新RevitLookup插件的童鞋。
Revit 2020 Lookup 是Revit查找工具,是Revit开发必不可少的一个组件,需要的朋友可以下载! 用法:将文件解压后找到 RevitLookup.addin和RevitLookup.dll放到C:\ProgramData\Autodesk\Revit\Addins\2020下即可
For Revit2019_LookUp源码,添加19revit*.dll引用后可直接编译,使用其生成dll,也可跟踪其代码,查看lookup原理
Revit二次开发必助插件revit lookup,辅助开发人员查看revit内部结构。方便开和学习内部结构
2015版RevitLookup.dll及RevitLookup.addin配有安装目录修改说明。
资源来自pypi官网。 资源全名:digdeo-syspass-ansible-lookup-0.2.4.tar.gz
revit lookup 2020安装包,编译好的安装包msi文件,一键安装即可方便快捷,安装之后打开Revit选择总是加载即可永久使用此插件。