简体   繁体   中英

spring xml based bean definition, class attribute of `bean` element

docs says:

"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.

So how to explain this case:

1)spring bean definition 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)test case:

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)The result:

class $Proxy14
true
false
false

4)I don't think classattribute.xml instantiates the bean entityManagerFactory with a static factory method since factory-method attribut of '' element is not specified.

5)Can anyone explain it? Thanks in advance!

Your bean is

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

The type LocalContainerEntityManagerFactoryBean is a FactoryBean<EntityManagerFactory> . This is a special type in Spring.

Interface to be implemented by objects used within a BeanFactory which are themselves factories. If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.

So Spring uses a LocalContainerEntityManagerFactoryBean object, with the properties you set, to generate an EntityManagerFactory object which it exposes as a bean with the name you provided. So the bean you've defined is actually of type EntityManagerFactory , not LocalContainerEntityManagerFactoryBean .

This is further discussed in the documentation, here . As it states, you can get the LocalContainerEntityManagerFactoryBean object.

When you need to ask a container for an actual FactoryBean instance itself instead of the bean it produces, preface the bean's id with the ampersand symbol ( & ) when calling the getBean() method of the ApplicationContext .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM