Spring学习笔记(3)

 

测试2中的例子

package  pojo;

import  org.springframework.context.ApplicationContext;

import  org.springframework.context.support.ClassPathXmlApplicationContext;

public   class  Text {

  public   static   void  main(String arg[]){

    ApplicationContext ac =  new  ClassPathXmlApplicationContext( "applicationContext.xml" );

    Person xiao = (XiaoMing)ac.getBean( "xiaoming" );

    xiao.eat();

  }  

}

Spring构造器注入

很快晓峰已经工作一年了,每天重复干着简单的工作很是无聊啊.不过社会总是在不断进步的。Roh Johnosn这个Spring国里著名的科学家有发明了一种机器。他能在孩子喊没有出生时就能知道这个孩子的一些基本需要。

晓峰听说现在这种机器很快就要装配到他们这里了,在这里工作一年了,因为还记着在地球的三国厚黑学,所以晓峰的人缘在这里还是很不错的.很早便打了报告希望到这个正在组建的“构造注入”部门工作.

今天晓峰接到通知,他可以去“构造注入”这个新部门了。晓峰明天就要去医院的接生部上班了.

晓峰拿到仪器到了预备接生部,给每一位即将出生的孩子进行预测

比如现在这个即将出生的孩子,他以后长大后会是一个很好的语言学家。晓峰要做到就是写封邮件发回总部。公务员会给他准备好各种语言类的图书

现在我们用java描述一下这件事情

Public class Baby {

Public Language lang;

Public Baby(Languange lang){

This.lang = lang;

}

Public void sayLanguage(){

System.out.println("say"+lang.getname);

}

}

Public class Languange{

Public String name="英语";

Public Language(){}

Public String getName(){

Return name;

}

}

Xml文件如下

<beans>

<bean id="baby" class="Baby">

<constructor-arg ref="language" />---->构造注入

</bean>

<bean id="language" class="Language"/>

</beans>

测试文件

Test.java文件

Public class Test{

Public static void mian(String[] args){

ApplicationContext ac =

 new  ClassPathXmlApplicationContext("bean.xml");

Baby b = (Baby)ac.getBean("baby");

b.sayLanguage();

}

}

结果是:say英语

其中xml文件描述的内容相当于下面的程序

Language lang = new Language();

Baby b = new Baby(lang);

两种注入方式的比较

这两种注入方式无所谓好与坏

值注入就相当于下面的样子

Person p = new Person();

p.setName("小花");

p.setAge("12");

一样。

构造注入就相当于下面的样子

Person p=  new Person("小花","12");一样,主要是看你 的习惯和程序要求了,当然他们还是有一些不同的。但是大家了解一下就可以了

比如:值注入

1. 程序开发人员更容易理解和接受。通过setter方法设定的依赖关系显得更加直观自然。

2. 对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿

3. 尤其是默写属性可选的情况下,多参数的构造器就更麻烦的

我个人很喜欢用值注入的方式,因为配置文件出错很容易找到

1. 构造注入可以在构造器中决定依赖关系注入的顺序

2. 对于依赖关系无须变化的Bean,构造注入更有用处.

3. 依赖关系只能在构造器中设定。因而只有组件的创建者才能改变组件的依赖关系。

下面我们来了解一下Spring是怎样实现这样的管理的

在Spring的国度里有一个最高的统治者BeanFactory 主席,他的下面还有一个副主席ApplicationContext。其中ApplicationContext也将是以后BeanFactory的继任者(拿Java语言来描述他们的关系就是:ApplicationContext是BeanFactory的子类)。所以他们也代表了整个Spring政府。

Spring是产生Bean的工厂,同时也管理着Spring世界里的所有Bean。Bean的说法就相当于我们现实世界里的人和物的统称。

我们要在Spring世界里很好的生活下去我们就要必须了解BeanFactory他的性格是什么,他的权力范围在哪里 这样我们才能有更好的漏洞去钻,赚更多的资本。活的更好

其中晓峰也是这样想的。所以,他通过自己的不断的盯梢、摸底得到了下面的BeanFactory的全部资料.

package org.springframework.beans.factory;

主席的家庭地址:BeanFactory住在org市springframework区beans街factory栋

作用:主席住的地方

import org.springframework.beans.BeansException;

主席的家庭别院在:org市springframework区beans街BeansExeption

作用:主席用来处理Spring国度里发生重大错误的时候使用的地方,只要主席去了,就一   定有大事发生。这里要重点注意

public  interface  BeanFactory {

姓名:BeanFactory

 

  String FACTORY_BEAN_PREFIX = "&";

如果要想得到主席的名字,就要进行转义,用Spring世界中的java语言来描述就是『

//这里是对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,   

    // 如果需要得到工厂本身,需要转义  

 

  Object getBean(String name) throws BeansException;

     主席的权利一:通过各种Bean的名字找到这个bean,就相当于现实世界的警察,知           道你的DNA就能找到你的人一样,因为在Spring世界中是不能重名           的。当然有时也是会出错的比如这个Bean已经去世了。

 

  Object getBean(String name, Class requiredType) 

throws BeansException;

主席的权利二:通过Bean的名字和Bean的类型来找到这个bean,相当于我们通过一         个人的DNA和他是那一个省的人来找到这个人一样.当然他也是有可能         出错的  

  boolean containsBean(String name);

主席的权利三:通过Bean的名字来找他在Spring国度里是否存在

 

  boolean isSingleton(String name)

 throws NoSuchBeanDefinitionException;

主席的权利四:通过Bean的名字找到这个Bean。看看他是不是在Spring中不能缺少的         重要人才.相当于我们现在的某某主席找到一个人的人名就可以知道他是         干什么的,是不是在我们国家内某个领域不可或缺的人才一样。           BranFactory就是通过这个权限来检查这个Bean是不是只要处理某一件事         情就只有他一个人才能完成别的人都不行。用java语言来描述就是所他         是不是单例的

 

  boolean isPrototype(String name) 

throws NoSuchBeanDefinitionException;

通过Bean的名字来判断他的作用域是不是Prototype

 

  boolean isTypeMatch(String name, Class targetType)

 throws NoSuchBeanDefinitionException;

通过Bean的名字来判断他的作用域是不是TypeMatch

 

  Class getType(String name) throws NoSuchBeanDefinitionException;

主席的权利五:通过Bean的名字知道他是那里的人,用Java语言描述就是,通过Bean       的名字知道Bean的类型

 

  String[] getAliases(String name);

主席特权利六:通过Bean的名字知道他还有没有什么别的名字

}

现在晓峰发现他只有找人和判断一个Bean能在那里工作的权利。嗯,权利很小啊!!!

BeanFactory有很多的孩子(也就是他有多个实现类),用来具体的执行它的这些权利。

我们经常能看到的是org.springframework.beans.xml.XmlBeanFactory

但是,Spring的国民通常是不去麻烦他们的,毕竟人家的地位最高么。因此直接管理spring国度的就只有主席的副手ApplicationContext了(ApplicationContext是BeanFactory的子接口)。

晓峰收集到的ApplicationContext的详细信息如下:

package org.springframework.context;

居住地:org市springframework区.context街(因为他比较有实权)

import org.springframework.beans.factory.HierarchicalBeanFactory;

import org.springframework.beans.factory.ListableBeanFactory;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import org.springframework.core.io.support.ResourcePatternResolver;

public  interface  ApplicationContext  extends  ListableBeanFactory, HierarchicalBeanFactory,

    MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

//姓名:ApplicationContext

 

  ApplicationContext getParent();

//返回他管理的bean的父亲,如果这个bean是孤儿的话,就返回空(null)

 

  AutowireCapableBeanFactory getAutowireCapableBeanFactory()

 throws IllegalStateException;

//给管理Bean一个 自动装配协作对象的接口,有五种方式

 

  String getDisplayName();

//得到管理该bean的管理类的实例

(如:

org.springframework.context.support.ClassPathXmlApplicationContext@1d05c81

 

  long getStartupDate();

//第一次管理该Bean时,得到的当时的时间(Long型毫秒数)

}

ApplicationContext的权限也不大,但是他的孩子们可是很厉害的,很有实权。

比如他最常见的两个孩子是(ApplicationContext的实现类)

1. FileSystemXmlApplicationContext

2. ClassPathXmlApplicationContext

我们看看他的两个孩子的详细信息

package org.springframework.context.support;

FileSystemXmlApplicationContext的住址:

Org市.springframework区.context街.support栋

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.core.io.FileSystemResource;

import org.springframework.core.io.Resource;

import org.springframework.util.StringUtils;

public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {

//姓名:FileSystemXmlApplicationContext

//地位:ApplicationContext的孩子(实现类)

  private String[] configLocations;

 

  public FileSystemXmlApplicationContext(String configLocation) throws BeansException {

    this(new String[] {configLocation}, true, null);

  }

//从xml文件中载入信息.创建一个新的FileSystemXmlApplicationContext类(Bean),configLocations是xml的名字

 

  public FileSystemXmlApplicationContext(String[] configLocations) throws BeansException {

    this(configLocations, true, null);

  }

//从多个xml文件中载入信息.创建一个新的FileSystemXmlApplicationContext类(Bean),configLocations是xml的名字

 

  public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {

    this(configLocations, true, parent);

  }

//从多个xml文件和ApplicationContext中载入信息

.创建一个新的FileSystemXmlApplicationContext类(Bean),configLocations是xml的名字

 

  public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {

    this(configLocations, refresh, null);

  }

//传入多个xml文件,是否自动更新上下文.返回新的FileSystemXmlApplicationContext类(Bean)

 

  public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)

      throws BeansException {

    super(parent);

    this.configLocations = StringUtils.trimArrayElements(configLocations);

    if (refresh) {

      refresh();

    }

  }

//需要多个xml文件、需要知道是否更新上下文、需要得到一个上下文。才能创建一个新的

FileSystemXmlApplicationContext

  protected String[] getConfigLocations() {

    return this.configLocations;

  }

//得到该FileSystemXmlApplicationContext中管理的描述Bean文件(全部xml文件)

 

  protected Resource getResourceByPath(String path) {

    if (path != null && path.startsWith("/")) {

      path = path.substring(1);

    }

    return new FileSystemResource(path);

  }

}

//得到resource 。resource用于访问XML配置文件资源

我们再来看看他的第二孩子的信息

ClassPathXmlApplicationContext

/**

住址:org市.springframework区.context街.support栋(他和他的兄弟

*        FileSystemXmlApplicationContex他住在一起)

*/

package org.springframework.context.support;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.core.io.ClassPathResource;

import org.springframework.core.io.Resource;

import org.springframework.util.Assert;

import org.springframework.util.StringUtils;

//姓名:ClassPathXmlApplicationContext

//他的基因来自AbstractXmlApplicationContext

public class ClassPathXmlApplicationContext  extends  AbstractXmlApplicationContext {

  private Resource[] configResources;

  private String[] configLocations;

  //需要XML来创建一个新的ClassPathXmlApplicationContext

  public ClassPathXmlApplicationContext(String configLocation) throws BeansException {

    this(new String[] {configLocation}, true, null);

  }

  //需要一组XML的文件名来创建一个新的ClassPathXmlApplicationContext

  public ClassPathXmlApplicationContext(String[] configLocations) throws BeansException {

    this(configLocations, true, null);

  }

 

  public ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {

    this(configLocations, true, parent);

  }

 

  public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {

    this(configLocations, refresh, null);

  }

 

  public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)

      throws BeansException {

    super(parent);

    this.configLocations = StringUtils.trimArrayElements(configLocations);

    if (refresh) {

      refresh();

    }

  }

 

  public ClassPathXmlApplicationContext(String path, Class clazz) throws BeansException {

    this(new String[] {path}, clazz);

  }

 

  public ClassPathXmlApplicationContext(String[] paths, Class clazz) throws BeansException {

    this(paths, clazz, null);

  }

 

  public ClassPathXmlApplicationContext(String[] paths, Class clazz, ApplicationContext parent)

      throws BeansException {

    super(parent);

    Assert.notNull(paths, "Path array must not be null");

    Assert.notNull(clazz, "Class argument must not be null");

    this.configResources = new Resource[paths.length];

    for (int i = 0; i < paths.length; i++) {

      this.configResources[i] = new ClassPathResource(paths[i], clazz);

    }

    refresh();

  }

  protected Resource[] getConfigResources() {

    return this.configResources;

  }

  protected String[] getConfigLocations() {

    return this.configLocations;

  }

}

我们可以看到他们兄弟俩完成的工作几乎就是一样的,那么他们有没有区别呢

FileSystemXmlApplication是以制定路径的Xml配置文件创立的ApplicationContext

ClassPathXmlApplicationContext是以CLASSPATH路径下的Xml配置文件创建

ApplicationContext

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值