Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)
我们到底能走多远系列(33)
扯淡:
各位:
命运就算颠沛流离
命运就算曲折离奇
命运就算恐吓着你做人没趣味
别流泪 心酸 更不应舍弃
...
主题:
Spring源码阅读还在继续,上篇文章初始化IoC容器:摸我
事实上前面的IOC容器初始化只是建立了BeanDefinition数据映射,而依赖注入的过程是在向Ioc容器索要bean的时候发生的。
getBean就是触发依赖注入的地方。
1,下面是AbstractBeanFactory的getBean实现。根据scop进行分支处理,比较清晰:
注意:关于spring中的 bean的scop属性,有两个很常用:singleton和prototype
singleton:这是Spring容器默认的作用域,使用singleton作用域生成的是单实例,在整个Bean容器中仅保留一个实例对象供所有调用者共享引用。单例模式对于那些无会话状态的Bean(如辅助工具类、DAO组件、业务逻辑组件等)是最理想的选择。
prototype: 原型模式,这是多实例作用域,针对每次不同的请求,Bean容器均会生成一个全新的Bean实例以供调用者使用。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public Object getBean(String name) throws BeansException { // 最终调用doGetBean方法 return doGetBean(name, null, null, false); } public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException { return doGetBean(name, requiredType, args, false); }
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 从已经建立的实例bean里找 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 取得本bean的依赖bean组 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { // 循环调用getBean方法,递归实现本bean的全部依赖 for (String dependsOnBean : dependsOn) { getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } // Create bean instance. // Singleton 情况 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // Prototype 情况 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); // 最终大家都调这个方法来实例化Bean prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { // 其他scop情况 String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } }
2,上面代码会调用到AbstractAutowireCapableBeanFactory 的 createBean方法,这个方法中调用了内部的doCreateBean方法,createBean方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } // Make sure bean class is actually resolved at this point. resolveBeanClass(mbd, beanName); // Prepare method overrides. try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbd); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } // 调用内部方法创建Bean Object beanInstance = doCreateBean(beanName, mbd, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
doCreateBean方法:
里面也就是调用createBeanInstance创建bean的方法真正出来一个bean后,在调用populateBean方法(链接)来初始化这个bean
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 创建bean的方法 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { // 初始化创建出来的bean populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
如此,我们先看createBeanInstance这个创建bean的方法是如何完成的。
注意:在spring中有三种实例化bean的方式:
一、使用构造器实例化,默认
<bean id="personService" class="cn.mytest.service.impl.PersonServiceBean"></bean>
二、使用静态工厂方法实例化
<bean id="personService1" class="cn.mytest.service.impl.PersonServiceFactory" factory-method="createPersonServiceBean"></bean>
三、使用实例化工厂方法实例化
<bean id="personServiceFactory" class="cn.mytest.service.impl.PersonServiceFactory"></bean> <bean id="personService2" factory-bean="personServiceFactory" factory-method="createPersonServiceBean1"></bean>
这在createBeanInstance中有体现:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point. Class beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } // 工厂方法实例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // Need to determine the constructor... // 构造函数实例化 Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); }
就直接看下简单常用的instantiateBean方法:
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { return getInstantiationStrategy().instantiate(mbd, beanName, parent); } }, getAccessControlContext()); } else { // spring默认的实例化策略是使用CGLIB来实例化bean beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
CGLIB:cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现。
使用CGLB实例化代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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. // 使用CGLIB实现实例化bean return instantiateWithMethodInjection(beanDefinition, beanName, owner); } } protected Object instantiateWithMethodInjection( RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) { // Must generate CGLIB subclass. return new CglibSubclassCreator(beanDefinition, owner).instantiate(null, null); } public Object instantiate(Constructor ctor, Object[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.beanDefinition.getBeanClass()); enhancer.setCallbackFilter(new CallbackFilterImpl()); enhancer.setCallbacks(new Callback[] { NoOp.INSTANCE, new LookupOverrideMethodInterceptor(), new ReplaceOverrideMethodInterceptor() }); return (ctor == null) ? enhancer.create() : enhancer.create(ctor.getParameterTypes(), args); }
到这里,创建bean的过程是完成了,关于bean的一些初始化的操作及调用populateBean方法下次再研究吧。
事实上spring提供了jvm的反射实现的代理,和cglib实现的代理,来实例化java对象。
下面就稍微学习下这两种不同的代理方式:
代理模式也是常用的设计模式,分为两种:静态代理和动态代理
静态代理:
/** * 定义一个账户接口 * * @author Administrator */ public interface Count { // 查看账户方法 public void queryCount(); // 修改账户方法 public void updateCount(); }
public class CountImpl implements Count { @Override public void queryCount() { System.out.println("查看账户方法..."); } @Override public void updateCount() { System.out.println("修改账户方法..."); } }
/** * 这是一个代理类(增强CountImpl实现类) * * @author Administrator * */ public class CountProxy implements Count { private CountImpl countImpl; /** * 覆盖默认构造器 * * @param countImpl */ public CountProxy(CountImpl countImpl) { this.countImpl = countImpl; } @Override public void queryCount() { System.out.println("事务处理之前"); // 调用委托类的方法; countImpl.queryCount(); System.out.println("事务处理之后"); } @Override public void updateCount() { System.out.println("事务处理之前"); // 调用委托类的方法; countImpl.updateCount(); System.out.println("事务处理之后"); } }
public class TestCount { public static void main(String[] args) { CountImpl countImpl = new CountImpl(); CountProxy countProxy = new CountProxy(countImpl); countProxy.updateCount(); countProxy.queryCount(); } }
动态代理:
public interface BookFacade { public void addBook(); }
public class BookFacadeImpl implements BookFacade { @Override public void addBook() { System.out.println("增加图书方法。。。"); } }
public class BookFacadeProxy implements InvocationHandler{ private Object target; /** * 绑定委托对象并返回一个代理类 * * @param target * @return */ public Object bind(Object target) { this.target = target; // 取得代理对象 // 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷) return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override /** * 调用方法 * Object proxy:指被代理的对象 * Method method:要调用的方法 * Object[] args:方法调用时所需要的参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("事物开始"); // 执行方法 result = method.invoke(target, args); System.out.println("事物结束"); return result; } }
public class TestProxy { public static void main(String[] args) { BookFacadeProxy proxy = new BookFacadeProxy(); BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl()); bookProxy.addBook(); } }
以上的代理方式需要有接口的类来可以,所以使用cglib弥补了这一缺点,这也是不同之处:
/** * 这个是没有实现接口的实现类 */ public class BookFacadeCglibImpl { public void addBook() { System.out.println("增加图书的普通方法..."); } }
public class BookFacadeCglib implements MethodInterceptor{ private Object target; /** * 创建代理对象 * * @param target * @return */ public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } @Override // 回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("事物开始"); proxy.invokeSuper(obj, args); System.out.println("事物结束"); return null; } }
public class TestCglib { public static void main(String[] args) { BookFacadeCglib cglib=new BookFacadeCglib(); BookFacadeCglibImpl bookCglib=(BookFacadeCglibImpl)cglib.getInstance(new BookFacadeCglibImpl()); bookCglib.addBook(); } }
总结:
学习是没有止境的,当我们学得更多的时候,我们就会发现自己不知道的东西越来越多。
设计模式很难学,今天看一遍明天就忘了,实际编码能想起来更难~
让我们继续前行
----------------------------------------------------------------------
努力不一定成功,但不努力肯定不会成功。
共勉。