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. 最新 拉卡拉java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.拉卡拉等10家互联网公司的校招Offer,因为某些自身原因最终选择了拉卡拉.6.7月主要是做系统复习.项目复盘.LeetCo ...

  2. 最新 百度java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.百度等10家互联网公司的校招Offer,因为某些自身原因最终选择了百度.6.7月主要是做系统复习.项目复盘.LeetCode ...

  3. Python hashlib加密模块

    hashlib模块 简介: hashlib模块是一个提供了字符串加密功能的模块,包含MD5和SHA的加密算法.具体的加密支持有: MD5,sha1,sha224,sha256, sha384, sha ...

  4. [转载]C# MemoryStream(内存流)

    MemoryStream位于System.IO命名空间,为系统内存提供流式的读写操作.常作为其他流数据交换时的中间对象操作. 1.MemoryStream类封装一个字节数组,在构造实例时可以使用一个字 ...

  5. JavaSE基础(一)--初识Java

    Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称.由James Gosling和同事们共同研发,并在1995年正式 ...

  6. Java面试 - 在Java中, 既然构造方法是一个方法,那么为什么不使用void 定义呢?

    Java程序编译器是根据代码结构来进行编译处理的,执行的时候也是根据代码结构来处理的. 如果在构造方法上使用void,那么此结构就会与普通方法的结构相同,这样编译器会认为此方法是一个 普通方法,而普通 ...

  7. 阿里云RocketMQ的生产者简单实现

    // MQ的应用场景有比如 订单变更消息可以通过产生这个事件的地方(比如前端调用后端的接口post一个订单,那么就是在这个mapping方法里做一个生产者[不过最好通过aop来实现,不然n多个接口都要 ...

  8. ConcurrentHashMap能完全替代HashTable吗?

    至此你应该能够明白,ConcurrentHashMap与HashTable都可以用于多线程的环境,但是当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间.因为C ...

  9. lubuntu踩坑全记录

    为了降低系统占用,毕业之后一直用lubuntu不用ubuntu...操作其实差不多,就是lubuntu有一些小坑坑:P 本文是我的踩坑全记录.长期更新. 调分辨率  升级命令lubuntu不出登录页面 ...

  10. python学习-11 运算符2

    布尔值 1.真 true 假false name = 'abc' c = 'c' in name print(c) 运算结果: True Process finished with exit code ...