spring IOC容器实例化bean

应用上下文
接口org.springframework.context.ApplicationContext代表了srping IoC 容器,负责实例化、配置和组装beans。容器依据配置元数据去实例化、配置、组装。配置元数据可以用XML、Java 注解、或者Java编码表示。在配置元数据中,可以定义组成应用的对象,以及对象之间的依赖关系。

ApplicationContext是一个高级工厂的接口,能维护各种bean以及他们之间依赖的注册。使用方法
T getBean(String name, Class requiredType)就能从定义的bean中获取实例
ApplicationContext能让你读取bean定义、访问他们.
ApplicationContext有多种实现,常用的有从类路径获取配置文件的ClasspathXmlApplicationContext,从文件路径加载配置文件的FileSystemXmlApplicationContext,从java类获取配置的AnnotationConfigApplicationContext。

Spring IoC容器使用某种格式的配置元数据;配置元数据,就是告诉Ioc容器如何将对象实例化、配置、组装。
Spring配置由Spring bean的定义组成,这些bean必须被容器管理,至少1个,通常会有多个。基于XML的配置元数据,大概这么配置,根节点中配置子节点。Java configuration使用是这样的,一个带有@Configuration类注解的类中,方法上使用@Bean方法注解。
bean定义
bean的定义要与应用中实际的类相一致。可以定义service 层的对象、Dao对象、类似Struts的表现成的对象、像Hibernate SessionFactories这样的基础对象,JMS队列等等。
下面的样例展示了基于XML配置元数据的基本格式:


 
   
   

id属性是个字串,是bean的唯一标示符。class属性定义了bean的类型,要使用类的全限定类名(含有包路径)。id属性的值,可以作为合作bean的引用标示符。
Spring IoC的实例化易如反掌。ApplicationContext构造函数支持定位路径,定位路径也可以是多个,它是标识实际资源的字串,容器使用该标识加载配置元数据,支持多种资源,比如:本地文件系统、CLASSPATH等等。
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

多个配置文件共同定义bean非常有用。通常,每个XML配置文件在你的架构中代表一个逻辑层或者一个模块。
你可以使用应用上下文(applicationContext)的构造函数去加载所有xml中定义的bean。这个构造函数使用多个资源定位,就像前面中提到的。或者,也可以用一个或者多个资源引用,即使用
标签加载其他文件定义的bean。

 
     
     
     
      

上例中,从三个外部文件加载定义的bean:services.xml,messageSource.xml,themeSource.xml。被引入的文件的路径对于引入配置文件来说都是相对路径,所以service.xml必须在引入配置文件的相同文件路径或者相同的类路径中。而messageSource.xml和themeSource.xml必须在引入配置文件所在的文件夹下的resouce
文件夹下。正如你所看到的 /开头会被忽略掉,因为这些路径是相对路径,推荐不要使用/开头的格式。

Spring IoC容器管理一个或多个bean。这些bean根据提供给容器的配置元数据创建的,比如使用XML格式
定义。在容器内部,这些bean的定义用 BeanDefinition对象表示,BeanDefinition包含了下列元数据:
全路径(含包路径)类名:代表bean的实际实现类。
Bean行为配置元素,它规定了bean在容器中行为(作用域,生命周期回调函数等等)
引用其他bean,就是为了bean能正常工作而所需的其他bean的引用。这些引用类也称为合作类或者依赖类。
其他配置,为实例设置的其他属性配置。比如说,管理连接池的bean的连接数,池大小的上限。

beans命名

bean有一个或者多个标示符。这些标示符必须是所在容器范围内必唯一的。通常情况一下,一个bean仅有一个标示符,如果有需求需要多个,多出来的将被当做别名。
在XML格式配置元数据中,使用 id或者 name属性来作为bean的标示符。id属性只能有1个。命名规范是字符数字混编(myBean,fooService,等等)。若想给bean起个别名,则可使用name属性来指定。
id和name属性不是bean所必须的。若未明确指定id或者name属性,容器会给它生成一个唯一name属性。当然了,如果你想通过bean的name属性引用,使用ref元素方式,就必须给bean指定 name了。之所以支持无name bean特性,是为了使内部类自动装配。

在bean的定义处指定所有别名有时候并不合适,然而,在其他配置文件中给bean设置别名却更为恰当。此法通常应用在大型系统的场景中,配置文件分散在各个子系统中,每个子系统都有本系统的bean定义。XML格式配置元数据,提供元素,可以搞定此用法。

这种情况下,在同容器中有个叫fromName的bean,再使用此别名定义之后,即可被当做toName来引用。

bean的实例化
bean的定义,本质是如何创建一个或多个对象的配方。容器被请求时,会解析配置元数据中的bean定义并封装,使用封装配置创建(或者获取)对象实例。

若使用XML格式配置元数据,得为将要实例化的对象指定类型(或者说是类),使用元素的class属性实现。class属性 映射到BeanDefinition类实例的Class属性(域),这个class属性是元素必须的。

定义使用使用静态工厂方法创建的bean时,得指定工厂方法类的作为class属性值,并且还得指定工厂方法类中用于创建bean的方法名称,作为factory-method属性值。工厂方法可以有参数,调用该方法即可返回对象实例,就像通过构造函数创建对象实例一样。此种bean定义是为了兼容遗留系统中的静态工厂

下面的bean定义,是使用工厂方法创建bean的方式。定义中,无需指定返回对象的类型(class),而是指定工厂方法类的class。下例中,createInstance()方法必须是一个static静态方法。



public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}

    public static ClientService createInstance() {
    return clientService;
    }
}   

使用实例工厂方法的方式实例化,是调用容器中已存在的bean的一个非静态方法来创建一个bean。用法是,1、class属性置空设置。
2、设置factory-bean属性,其值为当前容器(或者父容器)中bean的名字,该bean包含可供调用的创建对象的实例方法。
3、设置factory-method属性,其值为工厂方法名。




工厂类

public class DefaultServiceLocator {

    private static ClientService clientService = new ClientServiceImpl();
    private DefaultServiceLocator() {}

    public ClientService createClientServiceInstance() {
    return clientService;
    }
}

bean 作用域
单例作用域
单例bean只会产生一个实例,对于所有的请求,Spring容器都只会返回一个实例,默认的作用域就是单例的。
换句话说,当定义了单例bean,Srping容器只会创建一个实例,这个实例存储在单例池中,单例池应该属于缓存,接下来所有对于该单例bean的请求和引用,都将返回缓存中的对象。

prototype原型作用域

设置bean作用域为prototype,就是非单例,对于每次请求都将返回一个该类的新实例。也就是说,原型bean注入另一个bean,或者是请求原型bean,都是通过在容器上调用getBean()方法产生的。一般来说 ,原型bean用于有状态bean,单例bean用于无状态bean。

Request, session, and global session scopes
request
,session
,global session
作用域,只有在spring web ApplicationContext
的实现中(比如XmlWebApplicationContext
)才会起作用,若在常规Spring IoC容器中使用,比如ClassPathXmlApplicationContext
中,就会收到一个异常IllegalStateException
来告诉你不能识别的bean作用域

微信公众号: java技术
技术交流群: 245130488

你可能感兴趣的:(spring IOC容器实例化bean)