spring中有三中实例化bean的方式

来源:互联网 发布:安徽11选五任3遗漏数据 编辑:程序博客网 时间:2024/05/21 11:00

一、在spring中有三中实例化bean的方式:

1、使用构造器实例化;

2、使用静态工厂方法实例化;

3、使用实例化工厂方法实例化。

 

每种实例化所采用的配置是不一样的:

1、使用构造器实例化;

这种实例化的方式可能在我们平时的开发中用到的是最多的,因为在xml文件中配置简单并且也不需要额外的工厂类来实现。

 

Xml代码  收藏代码
  1. <!--applicationContext.xml配置:-->  
  2.   
  3. <bean id="personService" class="cn.mytest.service.impl.PersonServiceBean"></bean>  

 

 id是对象的名称,class是要实例化的类,然后再通过正常的方式进调用实例化的类即可,比如:

 

Java代码  收藏代码
  1. public void instanceSpring(){  
  2.                 //加载spring配置文件  
  3.         ApplicationContext ac = new ClassPathXmlApplicationContext(  
  4.                 new String[]{  
  5.                         "/conf/applicationContext.xml"  
  6.                 });  
  7.         //调用getBean方法取得被实例化的对象。  
  8.         PersonServiceBean psb = (PersonServiceBean) ac.getBean("personService");  
  9.           
  10.         psb.save();  
  11. }  

 

采用这种实例化方式要注意的是:要实例化的类中如果有构造器的话,一定要有一个无参的构造器。

 

2、使用静态工厂方法实例化;

根据这个中实例化方法的名称就可以知道要想通过这种方式进行实例化就要具备两个条件:(一)、要有工厂类及其工厂方法;(二)、工厂方法是静态的。OK,知道这两点就好办了,首先创建工程类及其静态方法:

 

Java代码  收藏代码
  1. package cn.mytest.service.impl;  
  2.   
  3. /** 
  4. *创建工厂类 
  5. * 
  6. */  
  7. public class PersonServiceFactory {  
  8.     //创建静态方法  
  9.     public static PersonServiceBean createPersonServiceBean(){  
  10.          //返回实例化的类的对象  
  11.         return new PersonServiceBean();  
  12.     }  
  13. }  

 然后再去配置spring配置文件,配置的方法和上面有点不同,这里也是关键所在

 

Xml代码  收藏代码
  1. <!--applicationContext.xml配置:-->  
  2.   
  3. <bean id="personService1" class="cn.mytest.service.impl.PersonServiceFactory" factory-method="createPersonServiceBean"></bean>  

 id是实例化的对象的名称,class是工厂类,也就实现实例化类的静态方法所属的类,factory-method是实现实例化类的静态方法。

然后按照正常的调用方法去调用即可:

 

Java代码  收藏代码
  1. public void instanceSpring(){  
  2.                 //加载spring配置文件  
  3.         ApplicationContext ac = new ClassPathXmlApplicationContext(  
  4.                 new String[]{  
  5.                         "/conf/applicationContext.xml"  
  6.                 });  
  7.         //调用getBean方法取得被实例化的对象。  
  8.         PersonServiceBean psb = (PersonServiceBean) ac.getBean("personService1");  
  9.           
  10.         psb.save();  
  11. }  

 

3、使用实例化工厂方法实例化。

这个方法和上面的方法不同之处在与使用该实例化方式工厂方法不需要是静态的,但是在spring的配置文件中需要配置更多的内容,,首先创建工厂类及工厂方法:

 没有静态方法,因此配置时,先实例化工厂,在实例化需要的bean。

Java代码  收藏代码
  1. package cn.mytest.service.impl;  
  2.   
  3. /** 
  4. *创建工厂类 
  5. * 
  6. */  
  7. public class PersonServiceFactory {  
  8.     //创建静态方法  
  9.     public PersonServiceBean createPersonServiceBean1(){  
  10.          //返回实例化的类的对象  
  11.         return new PersonServiceBean();  
  12.     }  
  13. }  
 

  然后再去配置spring配置文件,配置的方法和上面有点不同,这里也是关键所在

 

Xml代码  收藏代码
  1. <!--applicationContext.xml配置:-->  
  2.   
  3. <bean id="personServiceFactory" class="cn.mytest.service.impl.PersonServiceFactory"></bean>  
  4.   
  5. <bean id="personService2" factory-bean="personServiceFactory" factory-method="createPersonServiceBean1"></bean>  

 这里需要配置两个bean,第一个bean使用的构造器方法实例化工厂类,第二个bean中的id是实例化对象的名称,factory-bean对应的被实例化的工厂类的对象名称,也就是第一个bean的id,factory-method是非静态工厂方法。

 

 

然后按照正常的调用方法去调用即可:

 

Java代码  收藏代码
  1. public void instanceSpring(){  
  2.                 //加载spring配置文件  
  3.         ApplicationContext ac = new ClassPathXmlApplicationContext(  
  4.                 new String[]{  
  5.                         "/conf/applicationContext.xml"  
  6.                 });  
  7.         //调用getBean方法取得被实例化的对象。  
  8.         PersonServiceBean psb = (PersonServiceBean) ac.getBean("personService2");  
  9.           
  10.         psb.save();  
  11. }  

 

4.3.2 Instantiating beans

A bean definition essentially is a recipe for creating one or more objects. The container looks at the recipe for a named bean when asked, and uses the configuration metadata encapsulated by that bean definition to create (or acquire) an actual object.

If you use XML-based configuration metadata, you specify the type (or class) of object that is to be instantiated in the class attribute of the <bean/> element. This class attribute, which internally is aClass property on a BeanDefinition instance, is usually mandatory. (For exceptions, see the section called “Instantiation using an instance factory method” andSection 4.7, “Bean definition inheritance”.) You use the Class property in one of two ways:

  • Typically, to specify the bean class to be constructed in the case where the container itself directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java code using the new operator.
  • To specify the actual class containing the static factory method that will be invoked to create the object, in the less common case where the container invokes astatic factory method on a class to create the bean. The object type returned from the invocation of the static factory method may be the same class or another class entirely.

1、Instantiation with a constructor

When you create a bean by the constructor approach, all normal classes are usable by and compatible with Spring. That is, the class being developed does not need to implement any specific interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice. However, depending on what type of IoC you use for that specific bean, you may need a default (empty) constructor.

The Spring IoC container can manage virtually any class you want it to manage; it is not limited to managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-argument) constructor and appropriate setters and getters modeled after the properties in the container. You can also have more exotic non-bean-style classes in your container. If, for example, you need to use a legacy connection pool that absolutely does not adhere to the JavaBean specification, Spring can manage it as well.

With XML-based configuration metadata you can specify your bean class as follows:

<bean id="exampleBean" class="examples.ExampleBean"/><bean name="anotherExample" class="examples.ExampleBeanTwo"/>

For details about the mechanism for supplying arguments to the constructor (if required) and setting object instance properties after the object is constructed, seeInjecting Dependencies.

2、Instantiation with a static factory method

When defining a bean that you create with a static factory method, you use the class attribute to specify the class containing the static factory method and an attribute named factory-method to specify the name of the factory method itself. You should be able to call this method (with optional arguments as described later) and return a live object, which subsequently is treated as if it had been created through a constructor. One use for such a bean definition is to call static factories in legacy code.

The following bean definition specifies that the bean will be created by calling a factory-method. The definition does not specify the type (class) of the returned object, only the class containing the factory method. In this example, the createInstance() method must be a static method.

<bean id="clientService"    class="examples.ClientService"    factory-method="createInstance"/>
public class ClientService {    private static ClientService clientService = new ClientService();    private ClientService() {}    public static ClientService createInstance() {        return clientService;    }}

For details about the mechanism for supplying (optional) arguments to the factory method and setting object instance properties after the object is returned from the factory, see Dependencies and configuration in detail.

3、Instantiation using an instance factory method

Similar to instantiation through a static factory method, instantiation with an instance factory method invokes a non-static method of an existing bean from the container to create a new bean. To use this mechanism, leave the class attribute empty, and in the factory-bean attribute, specify the name of a bean in the current (or parent/ancestor) container that contains the instance method that is to be invoked to create the object. Set the name of the factory method itself with the factory-methodattribute.

<!-- the factory bean, which contains a method called createInstance() --><bean id="serviceLocator" class="examples.DefaultServiceLocator">    <!-- inject any dependencies required by this locator bean --></bean><!-- the bean to be created via the factory bean --><bean id="clientService"    factory-bean="serviceLocator"    factory-method="createClientServiceInstance"/>
public class DefaultServiceLocator {    private static ClientService clientService = new ClientServiceImpl();    private DefaultServiceLocator() {}    public ClientService createClientServiceInstance() {        return clientService;    }}

One factory class can also hold more than one factory method as shown here:

<bean id="serviceLocator" class="examples.DefaultServiceLocator">    <!-- inject any dependencies required by this locator bean --></bean><bean id="clientService"    factory-bean="serviceLocator"    factory-method="createClientServiceInstance"/><bean id="accountService"    factory-bean="serviceLocator"    factory-method="createAccountServiceInstance"/>
public class DefaultServiceLocator {    private static ClientService clientService = new ClientServiceImpl();    private static AccountService accountService = new AccountServiceImpl();    private DefaultServiceLocator() {}    public ClientService createClientServiceInstance() {        return clientService;    }    public AccountService createAccountServiceInstance() {        return accountService;    }}

This approach shows that the factory bean itself can be managed and configured through dependency injection (DI). See Dependencies and configuration in detail.

[Note]Note

In Spring documentation, factory bean refers to a bean that is configured in the Spring container that will create objects through an instance or staticfactory method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-specific FactoryBean.


二、bean的作用域:

默认情况为单例方式:scope=”singleton”
singleton
单实例作用域,这是Spring容器默认的作用域,使用singleton作用域生成的是单实例,在整个Bean容器中仅保留一个实例对象供所有调用者共享引用。单例模式对于那些无会话状态的Bean(如辅助工具类、DAO组件、业务逻辑组件等)是最理想的选择。
prototype
原型模式,这是多实例作用域,针对每次不同的请求,Bean容器均会生成一个全新的Bean实例以供调用者使用。prototype作用域非常适用于那些需要保持会话状态的Bean实例,有一点值得注意的就是,Spring不能对一个prototype Bean的整个生命周期负责,容器在初始化、装配好一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。因此,客户端要负责prototype实例的生命周期管理。
request
针对每次HTTP请求,Spring容器会根据Bean的定义创建一个全新的Bean实例, 且该Bean实例仅在当前HTTP request内有效,因此可以根据需要放心地更改所建实例的内部状态, 而其他请求中根据Bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。 当处理请求结束,request作用域的Bean实例将被销毁。该作用域仅在基于web的Spring ApplicationContext情形下有效。
session
针对某个HTTP Session,Spring容器会根据Bean定义创建一个全新的Bean实例,且该Bean实例仅在当前HTTP Session内有效。 与request作用域一样,我们可以根据需要放心地更改所创建实例的内部状态,而别的HTTP Session中根据Bean定义创建的实例, 将不会看到这些特定于某个HTTP Session的状态变化。 当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的Bean实例也会被废弃掉。该作用域仅在基于Web的Spring ApplicationContext情形下有效。
global session
global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的Web应用中才有意义。portlet规范定义了全局Session的概念,它被所有构成某个portlet Web应用的各种不同的portlet所共享。在global session作用域中定义的Bean被限定于全局portlet Session的生命周期范围内。如果我们是在编写一个标准的基于Servlet的Web应用,并且定义了一个或多个具有global session作用域的Bean,系统会使用标准的HTTP Session作用域,并且不会引起任何错误。该作用域仅在基于Web的Spring ApplicationContext情形下有效。

三、bean的生命周期:
(1)什么时候实例化?

对于单例的形式,在容器实例化的时候对bean进行实例化的。www.cdtarena.com

ApplicationContext ctx=new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});

单实例可以通过lazy-init=”true”,在getBean时进行实例化。

在beans里面default-lazy-init=”true”对所有bean进行延迟处理。

对于prototype,则是在getBean的时候被实例化的。

(2)在bean被实例化之后执行资源操作等方法:

Init-method=””

(3)在bean销毁之前执行的方法:

Destroy-method=””

什么时候被销毁?随着spring容器被关闭时被销毁。

调用spring容器的close方法来正常关闭。以前是随着应用程序执行完而关闭。


在Spring装载配置文件后,Spring工厂实例化完成,开始处理

(1)使用默认构造方法或指定构造参数进行Bean实例化。

(2)根据property标签的配置调用Bean实例中的相关set方法完成属性的赋值。

(3)如果Bean实现了BeanNameAware接口,则调用setBeanName()方法传入当前Bean的ID。

(4)如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory()方法传入当前工厂实例的引用。

(5)如果Bean实现了ApplicationContextAware接口,则调用setApplicationContext()方法传入当前ApplicationContext实例的引用。

(6)如果有BeanPostProcessor与当前Bean关联,则与之关联的对象的postProcess- BeforeInitialzation()方法将被调用。

(7)如果在配置文件中配置Bean时设置了init-method属性,则调用该属性指定的初始化方法。

(8)如果有BeanPostProcessor与当前Bean关联,则与之关联的对象的postProcess- AfterInitialzation()方法将被调用。

(9)Bean实例化完成,处于待用状态,可以被正常使用了。

(10)当Spring容器关闭时,如果Bean实现了DisposableBean接口,则destroy()方法将被调用。

(11)如果在配置文件中配置Bean时设置了destroy-method属性,则调用该属性指定的方法进行销毁前的一些处理。

(12)Bean实例被正常销毁。


参考文章:

http://jingyan.baidu.com/article/27fa7326c32db546f9271f6c.html

http://glzaction.iteye.com/blog/1286325

http://docs.spring.io/spring/docs/4.0.8.RELEASE/spring-framework-reference/htmlsingle/

0 0
原创粉丝点击