简体   繁体   English

基于Spring xml的bean定义,bean元素的类属性

[英]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 : 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)test case: 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)The result: 3)结果:

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. 4)我不认为classattribute.xml实例豆entityManagerFactory以来静态工厂方法factory-method的'不指定元素attribut。

5)Can anyone explain it? 5)有人可以解释吗? Thanks in advance! 提前致谢!

Your bean is 你的豆是

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

The type LocalContainerEntityManagerFactoryBean is a FactoryBean<EntityManagerFactory> . 类型LocalContainerEntityManagerFactoryBeanFactoryBean<EntityManagerFactory> This is a special type in Spring. 这是Spring中的一种特殊类型。

Interface to be implemented by objects used within a BeanFactory which are themselves factories. BeanFactory中使用的对象(本身就是工厂)实现的接口。 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. 如果bean实现此接口,则它将用作对象公开的工厂,而不是直接用作将自身公开的bean实例。

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. 因此,Spring使用具有您设置的属性的LocalContainerEntityManagerFactoryBean对象来生成EntityManagerFactory对象,该对象以具有您提供的name的Bean形式公开。 So the bean you've defined is actually of type EntityManagerFactory , not LocalContainerEntityManagerFactoryBean . 因此,您定义的bean实际上是EntityManagerFactory类型,而不是LocalContainerEntityManagerFactoryBean类型。

This is further discussed in the documentation, here . 有关详细信息,请参见此处的文档。 As it states, you can get the LocalContainerEntityManagerFactoryBean object. 如状态所示,您可以获取LocalContainerEntityManagerFactoryBean对象。

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 . 当您需要向容器询问一个实际的FactoryBean实例本身而不是它所产生的bean时,请在调用ApplicationContextgetBean()方法时在该bean的ID FactoryBean加上一个&符号( & )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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