Spring Ioc容器是负责管理Bean的,所以在继续学习Spring其他内容之前,我们需要首先了解一下Bean。

应用创建的java class,通过Spring IoC实例化创建对象并放入Spring IoC容器交给Spring IoC容器管理后,这个java对象就叫Bean。

Bean通过xml文件定义(bean标签),或者可以通过注解定义。Spring内部通过BeanDefinition管理Bean的定义信息(也叫元数据),BeanDefinition主要包括如下Bean定义的元数据:

  1. class name:全限定类名称,xml中通过class指定,注解方式的话就是该类的全限定类名。
  2. 行为属性:包括scope、lifecycle、callbacks等。
  3. 其他对象的引用:依赖对象。

Bean的命名

Spring IoC通过id唯一识别一个Bean,在整个Spring IoC容器中不重复。

通过xml文件配置Spring的时候,id一般是要求必须要指定的,但是通过注解方式配置的时候,id不需要指定。不指定id的情况下,Spring默认通过java.beans.Introspector.decapitalize转换类名生成id:类名首字母小写后生成id。

Bean的实例化

其实我们前面的文章已经说过了,有两种方式实例化Bean,一种是基于构造器的,一种是基于Factory Method。

Spring支持通过默认的无参构造器完成实例化,或者可以在配置文件指定构造器参数、Spring调用有参构造器完成实例化。底层实际都是通过java反射机制完成Bean的实例化。

通过Factory Method实例化有两种不同的形式,一种是静态工厂方法:

<bean id="clientService"
    class="examples.ClientService"
    factory-method="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"/>

通过实例工厂方法的方式实例化Bean,要求工厂类必须也是Spring IoC管理的Bean,这是显而易见的,很容易理解。

工厂类可以指定多个工厂方法,实例化多个Bean。

因此,这种情况下,Bean的真实类型就不能通过配置文件决定了,因为配置文件可能并没有指定class、即使指定了class,通过静态工厂方法创建的Bean的类型也是不确定的,是由工厂方法的返回值决定的,配置文件里不反应。也可以通过BeanFactory.getType在运行时获取到Bean的实际类型。

其实Spring的Bean实例化并不是这么简单,如果Spring发现当前类有AOP需求的话(比如方法加了@Transactional注解),那么Spring就需要通过CGLIB创建代理对象了,因为只有代理对象才能实现AOP,这部分内容我们暂时放一放。

上一篇 Spring FrameWork从入门到NB - 依赖注入DI
下一篇 Spring FrameWork从入门到NB - 自动装配


45 声望17 粉丝