当前位置: 首页 > news >正文

pc网站怎么建设流程wordpress my-account

pc网站怎么建设流程,wordpress my-account,WordPress最好的免费主题,网站建设收费标准渠道IoC容器是什么#xff1f; IoC文英全称Inversion of Control#xff0c;即控制反转#xff0c;我么可以这么理解IoC容器#xff1a; “把某些业务对象的的控制权交给一个平台或者框架来同一管理#xff0c;这个同一管理的平台可以称为IoC 容器。” 我们刚开始学习…IoC容器是什么 IoC文英全称Inversion of Control即控制反转我么可以这么理解IoC容器 “把某些业务对象的的控制权交给一个平台或者框架来同一管理这个同一管理的平台可以称为IoC 容器。” 我们刚开始学习spring的时候会经常看到的类似下面的这代码 上面代码中在创建ApplicationContext实例对象过程中会创建一个spring容器该容器会读取配置文 件cjj/models/beans.xml,并统一管理由该文件中定义好的所有bean实例对象如果要获取某个bean 实例使用getBean方法就行了。例如我们只需要将Person提前配置在beans.xml文件中可以理解为 注入之后我们可以不需使用new Person()的方式创建实例而是通过容器来获取Person实例这就 相当于将Person的控制权交由spring容器了差不多这就是控制反转的概念。 那在创建IoC容器时经历了哪些呢为此先来了解下Spring中IoC容器分类继而根据一个具体的容器 来讲解IoC容器初始化的过程。 Spring中有两个主要的容器系列 1. 实现BeanFactory接口的简单容器 2. 实现ApplicationContext接口的高级容器。 ApplicationContext appContext new ClassPathXmlApplicationContext(cjj/models/beans.xml); Person p (Person)appContext.getBean(person);ApplicationContext比较复杂它不但继承了BeanFactory的大部分属性还继承其它可扩展接口扩 展的了许多高级的属性其接口定义如下 public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, //继承于 BeanFactory HierarchicalBeanFactory,//继承于 BeanFactory MessageSource, // ApplicationEventPublisher,// ResourcePatternResolver //继承ResourceLoader用于获取resource对象 在BeanFactory子类中有一个DefaultListableBeanFactory类它包含了基本Spirng IoC容器所具有的 重要功能开发时不论是使用BeanFactory系列还是ApplicationContext系列来创建容器基本都会使用 到DefaultListableBeanFactory类可以这么说在spring中实际上把它当成默认的IoC容器来使用。下 文在源码实例分析时你将会看到这个类。 注文章有点长需要细心阅读不同版本的spring中源码可能不同但逻辑几乎是一样的如果可 以建议还是看源码 ^_^ 回到本文正题上来关于Spirng IoC容器的初始化过程在《Spirng技术内幕深入解析Spring架构与设 计原理》一书中有明确的指出IoC容器的初始化过程可以分为三步 1. Resource定位Bean的定义文件定位 2. 将Resource定位好的资源载入到BeanDefinition 3. 将BeanDefiniton注册到容器中 第一步 Resource定位 Resource是Sping中用于封装I/O操作的接口。正如前面所见在创建spring容器时通常要访问XML配 置文件除此之外还可以通过访问文件类型、二进制流等方式访问资源还有当需要网络上的资源时可 以通过访问URLSpring把这些文件统称为ResourceResource的体系结构如下: 常用的resource资源类型如下 FileSystemResource以文件的绝对路径方式进行访问资源效果类似于Java中的File; ClassPathResourcee以类路径的方式访问资源效果类似于 this.getClass().getResource(/).getPath();ServletContextResourceweb应用根目录的方式访问资源效果类似于 request.getServletContext().getRealPath(); UrlResource访问网络资源的实现类。例如file: http: ftp:等前缀的资源对象; ByteArrayResource: 访问字节数组资源的实现类。 那如何获取上图中对应的各种Resource对象呢 Spring提供了ResourceLoader接口用于实现不同的Resource加载策略该接口的实例对象中可以获取 一个resource对象也就是说将不同Resource实例的创建交给ResourceLoader的实现类来处理。 ResourceLoader接口中只定义了两个方法 Resource getResource(String location); //通过提供的资源location参数获取Resource实例 ClassLoader getClassLoader(); // 获取ClassLoader,通过ClassLoader可将资源载入JVM 注ApplicationContext的所有实现类都实现RecourceLoader接口因此可以直接调用 getResource参数获取Resoure对象。不同的ApplicatonContext实现类使用getResource方法取得 的资源类型不同例如FileSystemXmlApplicationContext.getResource获取的就是 FileSystemResource实例ClassPathXmlApplicationContext.gerResource获取的就是 ClassPathResource实例XmlWebApplicationContext.getResource获取的就是 ServletContextResource实例另外像不需要通过xml直接使用注解Configuation方式加载资源的 AnnotationConfigApplicationContext等等。 在资源定位过程完成以后就为资源文件中的bean的载入创造了I/O操作的条件如何读取资源中的数 据将会在下一步介绍的BeanDefinition的载入过程中描述。 *第二步 通过返回的*resource对象进行BeanDefinition的载入 1.什么是BeanDefinition? BeanDefinition与Resource的联系呢 官方文档中对BeanDefinition的解释如下 A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied by concrete implementations. 它们之间的联系从官方文档描述的一句话Load bean definitions from the specified resource中可见 一斑。 /** * Load bean definitions from the specified resource. * param resource the resource descriptor * return the number of bean definitions found * throws BeanDefinitionStoreException in case of loading or parsing errors */ int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException; 总之BeanDefinition相当于一个数据结构这个数据结构的生成过程是根据定位的resource资源 对象中的bean而来的这些bean在Spirng IoC容器内部表示成了的BeanDefintion这样的数据结构 IoC容器对bean的管理和依赖注入的实现都是通过操作BeanDefinition来进行的。 2.如何将BeanDefinition载入到容器 在Spring中配置文件主要格式是XML对于用来读取XML型资源文件来进行初始化的IoC 容器而 言该类容器会使用到AbstractXmlApplicationContext类该类定义了一个名为 loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 的方法用于获取BeanDefinition// 该方法属于AbstractXmlApplicationContect类 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { XmlBeanDefinitionReader beanDefinitionReader new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); this.initBeanDefinitionReader(beanDefinitionReader); // 用于获取BeanDefinition this.loadBeanDefinitions(beanDefinitionReader); } 此方法在具体执行过程中首先会new一个与容器对应的BeanDefinitionReader型实例对象然后将生成 的BeanDefintionReader实例作为参数传入loadBeanDefintions(XmlBeanDefinitionReader)继续往 下执行载入BeanDefintion的过程。例如AbstractXmlApplicationContext有两个实现类 FileSystemXmlApplicationContext、ClassPathXmlApplicationContext这些容器在调用此方法时会 创建一个XmlBeanDefinitionReader类对象专门用来载入所有的BeanDefinition。 下面以XmlBeanDefinitionReader对象载入BeanDefinition为例使用源码说明载入BeanDefinition的 过程 // 该方法属于AbstractXmlApplicationContect类protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources getConfigResources();//获取所有定位到的 resource资源位置用户定义 if (configResources ! null) { reader.loadBeanDefinitions(configResources);//载入resources } String[] configLocations getConfigLocations();//获取所有本地配置文件的位置 容器自身 if (configLocations ! null) { reader.loadBeanDefinitions(configLocations);//载入resources } } 通过上面代码将用户定义的资源以及容器本身需要的资源全部加载到reader中 reader.loadBeanDefinitions方法的源码如下// 该方法属于AbstractBeanDefinitionReader类, 父接口BeanDefinitionReader Override public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, Resource array must not be null); int counter 0; for (Resource resource : resources) { // 将所有资源全部加载交给AbstractBeanDefinitionReader的实现子类处理这些 resource counter loadBeanDefinitions(resource); } return counter; } BeanDefinitionReader接口定义了 int loadBeanDefinitionsResource resource方法 int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException; int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException; XmlBeanDefinitionReader 类实现了BeanDefinitionReader接口中的loadBeanDefinitions(Resource) 方法其继承关系如上图所示。XmlBeanDefinitionReader类中几主要对加载的所有resource开始进行 处理大致过程是先将resource包装为EncodeResource类型然后处理为生成BeanDefinition对 象做准备其主要几个方法的源码如下 public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { // 包装resource为EncodeResource类型 return loadBeanDefinitions(new EncodedResource(resource)); } // 加载包装后的EncodeResource资源 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, EncodedResource must not be null); if (logger.isInfoEnabled()) { logger.info(Loading XML bean definitions from encodedResource.getResource()); }try { // 通过resource对象得到XML文件内容输入流并为IO的InputSource做准备 InputStream inputStream encodedResource.getResource().getInputStream(); try { // Create a new input source with a byte stream. InputSource inputSource new InputSource(inputStream); if (encodedResource.getEncoding() ! null) { inputSource.setEncoding(encodedResource.getEncoding()); } // 开始准备 load bean definitions from the specified XML file return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( IOException parsing XML document from encodedResource.getResource(), ex); } } protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { // 获取指定资源的验证模式 int validationMode getValidationModeForResource(resource); // 从资源对象中加载DocumentL对象大致过程为将resource资源文件的内容读入到 document中 // DocumentLoader在容器读取XML文件过程中有着举足轻重的作用 // XmlBeanDefinitionReader实例化时会创建一个DefaultDocumentLoader型的私有 属性,继而调用loadDocument方法 // inputSource--要加载的文档的输入源 Document doc this.documentLoader.loadDocument( inputSource, this.entityResolver, this.errorHandler, validationMode, this.namespaceAware); // 将document文件的bean封装成BeanDefinition并注册到容器 return registerBeanDefinitions(doc, resource); } catch ...(略) } DefaultDocumentLoader大致了解即可感兴趣可继续深究其源码如下看完收起便于阅读下 文 View Code 上面代码分析到了registerBeanDefinitions(doc, resource)这一步也就是准备将Document中的Bean 按照Spring bean语义进行解析并转化为BeanDefinition类型这个方法的具体过程如下/** * 属于XmlBeanDefinitionReader类 * Register the bean definitions contained in the given DOM document. * param doc the DOM document * param resource * return the number of bean definitions found * throws BeanDefinitionStoreException */ public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { // 获取到DefaultBeanDefinitionDocumentReader实例 BeanDefinitionDocumentReader documentReader createBeanDefinitionDocumentReader(); // 获取容器中bean的数量 int countBefore getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; } 通过 XmlBeanDefinitionReader 类中的私有属性 documentReaderClass 可以获得一个 DefaultBeanDefinitionDocumentReader 实例对象 private Class? documentReaderClass DefaultBeanDefinitionDocumentReader.class; protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() { return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.document ReaderClass)); } DefaultBeanDefinitionDocumentReader实现了BeanDefinitionDocumentReader接口它的 registerBeanDefinitions方法定义如下 // DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext readerContext; logger.debug(Loading bean definitions); // 获取doc的root节点通过该节点能够访问所有的子节点 Element root doc.getDocumentElement(); // 处理beanDefinition的过程委托给BeanDefinitionParserDelegate实例对象来完成 BeanDefinitionParserDelegate delegate createHelper(readerContext, root); // Default implementation is empty. // Subclasses can override this method to convert custom elements into standard Spring bean definitions preProcessXml(root); // 核心方法代理 parseBeanDefinitions(root, delegate);postProcessXml(root); } 上面出现的BeanDefinitionParserDelegate类非常非常重要需要了解代理技术如JDK动态代理、 cglib动态代理等。Spirng BeanDefinition的解析就是在这个代理类下完成的此类包含了各种对符合 Spring Bean语义规则的处理比如、、等的检测。 parseBeanDefinitions(root, delegate)方法如下 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl root.getChildNodes(); // 遍历所有节点做对应解析工作 // 如遍历到import标签节点就调用importBeanDefinitionResource(ele)方法对应 处理 // 遍历到bean标签就调用processBeanDefinition(ele,delegate)方法对应处理 for (int i 0; i nl.getLength(); i) { Node node nl.item(i); if (node instanceof Element) { Element ele (Element) node; if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } else { //对应用户自定义节点处理方法 delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } } private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { // 解析import标签 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } // 解析alias标签 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } // 解析bean标签,最常用过程最复杂 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } // 解析beans标签 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele);} } 这里针对常用的标签中的方法做简单介绍其他标签的加载方式类似 /** * Process the given bean element, parsing the bean definition * and registering it with the registry. */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { // 该对象持有beanDefinition的name和alias可以使用该对象完成beanDefinition向容 器的注册 BeanDefinitionHolder bdHolder delegate.parseBeanDefinitionElement(ele); if (bdHolder ! null) { bdHolder delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // 注册最终被修饰的bean实例下文注册beanDefinition到容器会讲解该方法 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error(Failed to register bean definition with name bdHolder.getBeanName() , ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } } parseBeanDefinitionElement(Element ele)方法会调用parseBeanDefinitionElement(ele, null)方法 并将值返回BeanDefinitionHolder类对象这个方法将会对给定的标签进行解析如果在解析标签的 过程中出现错误则返回null。 需要强调一下的是parseBeanDefinitionElement(ele, null)方法中产生了一个抽象类型的BeanDefinition 实例这也是我们首次看到直接定义BeanDefinition的地方这个方法里面会将标签中的内容解析到 BeanDefinition中之后再对BeanDefinition进行包装将它与beanName,Alias等封装到 BeanDefinitionHolder 对象中该部分源码如下 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { return parseBeanDefinitionElement(ele, null); } public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { String id ele.getAttribute(ID_ATTRIBUTE);String nameAttr ele.getAttribute(NAME_ATTRIBUTE); ...(略) String beanName id; ...略 // 从上面按过程走来首次看到直接定义BeanDefinition // 该方法会对bean节点以及其所有子节点如property、List、Set等做出解析具 体过程本文不做分析太多太长 AbstractBeanDefinition beanDefinition parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition ! null) { if (!StringUtils.hasText(beanName)) { ...(略) } String[] aliasesArray StringUtils.toStringArray(aliases); return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; } 第三步将BeanDefiniton注册到容器中 最终Bean配置会被解析成BeanDefinition并与beanName,Alias一同封装到BeanDefinitionHolder 类中 之后beanFactory.registerBeanDefinition(beanName, bdHolder.getBeanDefinition())注册 到DefaultListableBeanFactory.beanDefinitionMap中。之后客户端如果要获取Bean对象Spring容 器会根据注册的BeanDefinition信息进行实例化。 BeanDefinitionReaderUtils类 public static void registerBeanDefinition( BeanDefinitionHolder bdHolder, BeanDefinitionRegistry beanFactory) throws BeansException { // Register bean definition under primary name. String beanName bdHolder.getBeanName(); // 注册beanDefinition!!! beanFactory.registerBeanDefinition(beanName, bdHolder.getBeanDefinition()); // 如果有别名的话也注册进去Register aliases for bean name, if any. String[] aliases bdHolder.getAliases(); if (aliases ! null) { for (int i 0; i aliases.length; i) { beanFactory.registerAlias(beanName, aliases[i]); } } }DefaultListableBeanFactory实现了上面调用BeanDefinitionRegistry接口的 registerBeanDefinition( beanName, bdHolder.getBeanDefinition())方法这一部分的主要逻辑是向 DefaultListableBeanFactory对象的beanDefinitionMap中存放beanDefinition当初始化容器进行 bean初始化时在bean的生命周期分析里必然会在这个beanDefinitionMap中获取beanDefition实 例有机会成文分析一下bean的生命周期到时可以分析一下如何使用这个beanDefinitionMap。 registerBeanDefinition( beanName, bdHolder.getBeanDefinition() )方法具体方法如下 /** Map of bean definition objects, keyed by bean name */ private final MapString, BeanDefinition beanDefinitionMap new ConcurrentHashMapString, BeanDefinition(256); public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, Bean name must not be empty); Assert.notNull(beanDefinition, Bean definition must not be null); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, Validation of bean definition failed, ex); } } // beanDefinitionMap是个ConcurrentHashMap类型数据用于存放 beanDefinition,它的key值是beanName Object oldBeanDefinition this.beanDefinitionMap.get(beanName); if (oldBeanDefinition ! null) { if (!this.allowBeanDefinitionOverriding) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, Cannot register bean definition [ beanDefinition ] for bean beanName : theres already [ oldBeanDefinition ] bound); } else { if (logger.isInfoEnabled()) { logger.info(Overriding bean definition for bean beanName : replacing [ oldBeanDefinition ] with [ beanDefinition ]); } } } else { this.beanDefinitionNames.add(beanName); } // 将获取到的BeanDefinition放入Map中容器操作使用bean时通过这个 HashMap找到具体的BeanDefinition
http://www.w-s-a.com/news/312277/

相关文章:

  • 个人网站建设论文中期报告申报网站建设理由 模板
  • 岫岩做网站软件开发和app开发的区别
  • 邯郸质量一站式服务平台上线如何做国外销售网站
  • 内蒙古工程建设协会网站sem优化策略
  • Linux网站建设总结建设电子商务平台
  • 公司网站背景图片课程网站如何建设
  • 用js做简单的网站页面互联网技术对人力资源管理的影响有哪些
  • 银川做网站贵德县wap网站建设公司
  • 深圳网站建设zvge山西省煤炭基本建设局网站
  • 佛山网页网站设计线上怎么做推广和宣传
  • 多个域名绑定同一个网站案例
  • 建设网站都需要准备什么代理加盟微信网站建设
  • 网站备案没有了wordpress 添加按钮
  • 湖南建设银行宣传部网站福田蒙派克空调滤芯安装位置图
  • wap网站搜索wordpress工作室模板
  • 青岛金融网站建设如何提交网站地图
  • 制作简单门户网站步骤网站建设论文的摘要
  • 可以直接进入网站的正能量照片学做静态网站
  • 织梦做社交网站合适吗网站的市场如何制作
  • 阳曲网站建设价格多少四川佳和建设工程网站
  • 免费注册店铺位置sem seo什么意思
  • 建筑网站搜图电子商务网站建设渠道
  • 学校网站内容四川手机网站开发
  • 网站制作公司违法商业网站运营成本
  • 显示佣金的网站是怎么做的广告设计主要做哪些
  • 做阿里网站的分录济南seo网站排名关键词优化
  • 北京建设银行纪念钞预定官方网站wordpress中文优化版
  • 宝安做棋牌网站建设找哪家效益快创意设计师个人网站
  • 做线上网站需要多少钱系统开发板价格
  • 建筑企业登录哪个网站wordpress feed地址