基于spring xml的bean定义,`bean`元素的class属性

时间:2015-02-05 06:34:08

标签: java xml spring jpa

docs说:

"The class attribute defines the type of the bean and uses the fully qualified classname. "

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 a static 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)spring bean定义XML classattribute.xml:     

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="user" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    <property name="driverClass" value="${jdbc.driverClass}"></property>
    <property name="minPoolSize" value="${connpool.minSize}"></property>
    <property name="maxPoolSize" value="${connpool.maxSize}"></property>
</bean>

<!-- EntityManagerFactory -->
<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="packagesToScan" value="${entity.package}"></property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.show_sql">true</prop>
            <!-- other props -->
        </props>
    </property>
</bean>

2)测试用例:

import javax.persistence.EntityManagerFactory;
//...

private ApplicationContext ctx;

@Test
public void test(){
    Object bean = ctx.getBean("entityManagerFactory");
    System.out.println(bean.getClass());
    System.out.println(bean instanceof EntityManagerFactory);
    System.out.println(new LocalContainerEntityManagerFactoryBean() instanceof EntityManagerFactory);
    System.out.println(new LocalContainerEntityManagerFactoryBean().getClass() == bean.getClass());
}


@Before
public void setUp() {
    ctx = new ClassPathXmlApplicationContext("classattribute.xml");
}

3)结果:

class $Proxy14
true
false
false

4)我不认为classattribute.xml使用静态工厂方法实例化bean entityManagerFactory,因为未指定'{1}}''元素的属性。

5)任何人都可以解释一下吗?提前谢谢!

1 个答案:

答案 0 :(得分:2)

你的豆是

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

LocalContainerEntityManagerFactoryBean类型是FactoryBean<EntityManagerFactory>。这是Spring中的一种特殊类型。

  

BeanFactory中使用的对象实现的接口   他们自己是工厂。 如果bean实现了这个接口,那就是   用作公开对象的工厂,而不是直接作为bean   将暴露自己的实例。

所以Spring使用一个LocalContainerEntityManagerFactoryBean对象,使用你设置的属性来生成一个EntityManagerFactory对象,它以你提供的name作为bean公开。因此,您定义的bean实际上是EntityManagerFactory类型,而不是LocalContainerEntityManagerFactoryBean

文档here进一步讨论了这一点。如它所述,您可以获得LocalContainerEntityManagerFactoryBean对象。

  

当您需要向容器询问实际的FactoryBean实例时   它本身而不是它产生的bean,以bean的id为前缀   &符号(&)在调用getBean()方法时   ApplicationContext