java系统找不到指定文件怎么解决
304
2022-08-25
深入了解 Spring IOC DI 原理
什么是 IOC
IOC 被称为控制反转,通俗的说就是 我们需要使用一个对象而我们不在由自己去实现控制而交给Spring框架来控制对象的使用。
先上图:
未使用spring框架
使用spring框架
可以看到 Spring将我们的控制权由对象A转移到Spring进行。
那么什么是DI( 依赖注入 )? 这个虽然和控制反转将的是一个概念,但是DI是从被调用者的角度来讲的。如上图,我们被依赖的对象B不需要由A来控制而是需要通过我们的Spring来将B对象注入到Spring中然后直接由A来使用,所以叫依赖注入。为什么使用Spring IOC 当我们一个庞大的项目需要用到很多的对象,如果每使用一个对象都要由程序员去new 的话会造成大量的工作量。而最重要的一点就是管理问题,就像一个公司 一样,如果所有的人员都可以互相调度使用那么必定会造成一个混乱不堪的现象。但Spring IOC 容器那么就会充当一个管理调度的工作,他可以给人员提供一个有序的管理。深入 Spring IOC IOC 架构 有 ApplicationContext 和 BeanFactory 两种实现方法。 根据我们的实例分析源码:
首先我们有一个目标类Library,如下
public class Library { private String id;
private String address;public String getId() { return id;}public void setId(String id) { this.id = id;}public String getAddress() { return address;}public void setAddress(String address) { this.address = address;}@Overridepublic String toString() { return "com.wy.bean.Library{" + "id='" + id + '\'' + ", address='" + address + '\'' + '}';}
} 这里我们通过ApplicationContext对配置信息进行装配并进行实例化(在FileSystemXmlApplicationContext 中实例化)
ApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/application.xml");Library library = (Library) context.getBean("library");
而BeanFactory是先进行xml装配而不进行实例化的,他会在getBean()时候进行实例化
Resource resource=new ClassPathResource("application.xml"); BeanFactory factory=new DefaultListableBeanFactory(); BeanDefinitionReader bdr=new XmlBeanDefinitionReader((BeanDefinitionRegistry) factory); bdr.loadBeanDefinitions(resource); BeanFactory factory2 = new XmlBeanFactory(resource); Library library2 =(Library) factory2.getBean("library");
BeanFactory基础接口
BeanFactory是我们的顶级接口,其接口属性如下:
BeanFactory接口属性 getBean() 方法:该方法实现是在 AbstractBeanFactory 中实现
public Object getBean(String name, Object... args) throws BeansException { return this.doGetBean(name, (Class)null, args, false);}
真的方法应该是doGetBean(),可大概了解一下
protected
我们仔细看其中的这样其中有下面一段代码,我们在创建Bean的时候根据我们的属性去设置,分别根据我们的配置(单例,原型)执行不同的实例化方式,最后都到createBean()中去进行实例化
//单例模式if (mbd.isSingleton()) { sharedInstance = this.getSingleton(beanName, () -> { try { //创建实例 return this.createBean(beanName, mbd, args); } catch (BeansException var5) { this.destroySingleton(beanName); throw var5; } }); bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);//原型模式 } else if (mbd.isPrototype()) { var11 = null; Object prototypeInstance; try { this.beforePrototypeCreation(beanName); //创建实例 prototypeInstance = this.createBean(beanName, mbd, args); } finally { this.afterPrototypeCreation(beanName); } bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);//scope 模型 } else { String scopeName = mbd.getScope(); Scope scope = (Scope)this.scopes.get(scopeName); if (scope == null) {如下 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); }createBean()方法如下 ,其真正实例化的方法是在doCreateBean()中protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载 resolveBeanClass(mbd, beanName); //校验和准备Bean中的方法覆盖 try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建//Bean的代理对象 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()方法的详细代码解释
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { //封装被创建的Bean对象 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()){ //单态模式的Bean,先从容器中缓存中获取同名Bean instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //创建实例对象 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); //获取实例化对象的类型 Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); //调用PostProcessor后置处理器 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references //向容器中缓存单态模式的Bean对象,以防循环引用 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); } }); } //Bean对象的初始化,依赖注入在此触发 //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean Object exposedObject = bean; try { //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //初始化Bean对象 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) { //获取指定名称的已注册的单态模式Bean对象 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { //根据名称获取的以注册的Bean和正在实例化的Bean是同一个 if (exposedObject == bean) { //当前实例化的Bean初始化完成 exposedObject = earlySingletonReference; } //当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set
进入到 无参构造方法中 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); 这段代码就发现,春天来了!实例化,wc!
@Override 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"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction
使用Beanutil 的实例化代码!使用的是反射的newInstance()方法!
return ctor.newInstance(argsWithDefaultValues); 通过以上代码算是了解到底层进行实例化的代理设计模式,CGLIB动态代理,进入动态代理我们发现下面这段代码,使用的是反射的newInstance()进行了最终的实例化!
Constructor> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes()); instance = enhancedSubclassConstructor.newInstance(args);
看完实例化的源码后我们总结一下BeanFactory实例化的简单流程:
通过使用BeanFacrory 的 getBean()接口 来告诉IOC容器需要根据beanName获取实例getBean() 由 AbstractBeanFactory 的 dogetBean()具实现doGetBean()中我们需要首先去获取是否存在,然后对配置信息进行一个判断。然后去进入到实例化的方法进入 createBean() 选择在实例化前进行校验doCreateBean() 来对我们配置的模型进行实例化的具体实现并且在实例化后完成依赖注入。doCreateBean() 实例化的具体实现是在createBeanInstance()中进行的,他会根据我们的要求去进行相应的模式设计!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~