关于java:Spring-Bean的实例化

3次阅读

共计 1213 个字符,预计需要花费 4 分钟才能阅读完成。

Bean 的实例化

结构器的抉择

SimpleInstantiationStrategy

Bean 实例化有两种策略,一种是 CGLIB,另一种是通过 BeanUtil,即用 JVM 反射生成对象。
如果 Bean 中有 @LookUp 注解,或者 xml 中指定了 lookup-method,那么就会采纳 CGLIB 来实例化对象,因为须要重写@LookUp 标记的办法,这种状况下很容易想到应用代理,应用代理,被代理类又不需实现接口,无疑 CGLB 形式适合。

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
   // Don't override the class with CGLIB if no overrides.
 if (!bd.hasMethodOverrides()) {
      Constructor<?> constructorToUse;
 synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
 if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();
 if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");
 }
 // 获取无参结构器去实例化 Bean
            try {if (System.getSecurityManager() != null) {
                  constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
 }
               else {constructorToUse = clazz.getDeclaredConstructor();
 }
               bd.resolvedConstructorOrFactoryMethod = constructorToUse;
 }
            catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);
 }
         }
      }
      // 通过 JVM 反射性能生成实例化对象
      return BeanUtils.instantiateClass(constructorToUse);
 }
   else {
      // 通过 CGLIB 来生成实例化对象
 return instantiateWithMethodInjection(bd, beanName, owner);
 }
}
正文完
 0