spring对类的实例化,定义了接口InstantiationStrategy,同时先做了个简单实现类SimpleInstantiationStrategy。采用实现部分,抽象部分的策略。为了更好的扩展性,把一部分再次抽象,后面可以采用多种实现方式。
 
     下面具体代码分析:
public class SimpleInstantiationStrategy implements InstantiationStrategy {

    // FactoryMethod的ThreadLocal对象,线程所有的变量
private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<Method>(); // 返回当前线程所有的FactoryMethod变量值
public static Method getCurrentlyInvokedFactoryMethod() {
return currentlyInvokedFactoryMethod.get();
} // 第一种实例化方法,实现部分,部分抽象
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// bd对象定义里,是否包含MethodOverride列表;spring有两个标签参数会产生MethodOverrides ,分别是 lookup-method,replaced-method
// 没有MethodOverride对象,可以直接实例化
if (bd.getMethodOverrides().isEmpty()) {
// 实例化对象的构造方法
Constructor<?> constructorToUse;
// 锁定对象,使获得实例化构造方法线程安全
synchronized (bd.constructorArgumentLock) {
// 查看bd对象里是否含有
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
// 没有就生成
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
// 生成成功后,赋值给bd对象,后面使用
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 反射生成对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 有MethodOverride对象,需要使用另一种实现方式,之类实现
return instantiateWithMethodInjection(bd, beanName, owner);
}
} // 第一种实例化方法的抽象部分
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
} // 第二种实例化方法,实现部分,抽象部分
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
// 查看bd对象是否有MethodOverride对象
// 没有MethodOverride,则直接实例化对象
if (bd.getMethodOverrides().isEmpty()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
}
});
}
// 反射实例化对象
return BeanUtils.instantiateClass(ctor, args);
}
else {
// 有MethodOverride,之类实现实例化方法
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
} // 第二种实例化方法的抽象部分
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
} // 第三种实例化方法,全部实现
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
Object factoryBean, final Method factoryMethod, Object... args) { try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
}
});
}
else {
ReflectionUtils.makeAccessible(factoryMethod);
} // currentlyInvokedFactoryMethod,这块暂时还没看到在哪个地方用到了
// 先取出原有的 Method
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
// 设置当前的Method
currentlyInvokedFactoryMethod.set(factoryMethod);
// 使用factoryMethod实例化对象
return factoryMethod.invoke(factoryBean, args);
}
finally {
// 实例化完成,恢复现场
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
}
else {
currentlyInvokedFactoryMethod.remove();
}
}
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(factoryMethod.getReturnType(),
"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(factoryMethod.getReturnType(),
"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
}
catch (InvocationTargetException ex) {
String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
"declaring the factory method as static for independence from its containing instance. " + msg;
}
throw new BeanInstantiationException(factoryMethod.getReturnType(), msg, ex.getTargetException());
}
} }
 
注:lookup-method, replaced-method的使用,可以看之前的文章。 
 

spring实例化二:SimpleInstantiationStrategy的更多相关文章

  1. Spring实例

    Spring实例 上次的博文中 深入浅出Spring(二) IoC详解 和 深入浅出Spring(三) AOP详解中,我们分别介绍了一下Spring框架的两个核心一个是IoC,一个是AOP.接下来我们 ...

  2. spring实例教程

    1.配置好spring mvc发现访问无法匹配,很可能是文件放的位置或者相对目录不对. 2.实例大全:http://www.yiibai.com/spring/spring-collections-l ...

  3. 深入浅出Spring(四) Spring实例分析

    上次的博文中 深入浅出Spring(二) IoC详解 和 深入浅出Spring(三) AOP详解中,我们分别介绍了一下Spring框架的两个核心一个是IoC,一个是AOP.接下来我们来做一个Sprin ...

  4. [置顶] 深入浅出Spring(四) Spring实例分析

    上次的博文中 深入浅出Spring(二) IoC详解 和 深入浅出Spring(三) AOP详解中,我们分别介绍了一下Spring框架的两个核心一个是IoC,一个是AOP.接下来我们来做一个Sprin ...

  5. Redis + Jedis + Spring 实例(对象的操作)

        目录(?)[+] 不得不说,用哈希操作来存对象,有点自讨苦吃! 不过,既然吃了苦,也做个记录,也许以后API升级后,能好用些呢?! 或许,是我的理解不对,没有真正的理解哈希表. 一.预期 接上 ...

  6. spring实例入门

    首先是bean文件: package onlyfun.caterpillar; public class HelloBean {    private String helloWord = " ...

  7. spring 实例 bean 的方式

    一.使用构造器实例化: <bean id="personService" class="cn.mytest.service.impl.PersonServiceBe ...

  8. dubbo+zookeeper+spring实例

    互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...

  9. Struts2 + Spring + hibernate 框架搭成实例

    1.准备Jar包: struts2.hibernate.spring所需jar包   struts-core-2.x.x.jar  ----struts核心包 xwork-core-2.x.x.jar ...

随机推荐

  1. Django_03_模板的使用

    {{ }} 变量 list类型用 'lst.索引',且不支持倒序索引,即不能识别lst.-1 dic类型用 'dic.key',去取对应的value,不支持{} 对于实例对象,通常自己重写__str_ ...

  2. webpack官网demo起步中遇到的问题

    在webpack官网demo一开始搭建中 

  3. python_网络编程_基础

    基本的架构有C/S架构 和B/S架构 B/S架构优于C/S架构? 因为统一入口 , 都是从浏览器开始访问 两台电脑实现通信, 需要网卡, 网卡上有全球唯一的mac地址 ARP协议 #通过ip地址就能找 ...

  4. C# 自定义特性(Attribute)详解

    什么是特性 特性的定义:公共语言运行时允许添加类似关键字的描述声明,叫做attribute,它对程序中的元素进行标注,如类型.字段.方法.和属性等.attribute和.NetFramework文件的 ...

  5. 《Tsinghua os mooc》第11~14讲 进程和线程

    第十一讲 进程和线程 进程 vs 程序 程序 = 文件 (静态的可执行文件) 进程 = 执行中的程序 = 程序 + 执行状态 进程的组成包括程序.数据和进程控制块 同一个程序的多次执行过程对应为不同进 ...

  6. SecureCRT 配色方案

    整体效果: 一:Options -- Global Options 1.Normal colors     2.Bold colors 二 :Options -- Session Options 1. ...

  7. 第6章:LeetCode--数组(冒泡排序、快速排序)

    11. Container With Most Water class Solution { public: int maxArea(vector<int>& height) { ...

  8. python对影评进行评论分析,形成词云图

    1 # -*- coding:utf-8 -*-   2 '''   3 抓取豆瓣电影某部电影的评论  4抓取电影   5 网址链接:https://movie.douban.com/subject/ ...

  9. Vue路由系统

    Vue路由系统 一切分离都是为了更好的结合,本文详细介绍了前后端分离架构之后,前端如何实现路由控制,即Vue路由系统. 一.VueRouter实现原理 VueRouter的实现原理是根据监控锚点值的改 ...

  10. 关于Basic Latin踩到的一些坑

    目录 在wiki中,很多语言的字符集都包含了Basic Latin,一开始我没有细看,以为Basic Latin里面都是正常的字符集,后来在线上环境出现了问题 博主某天接到一个需求,需要过滤出某国语言 ...