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)任何人都可以解释一下吗?提前谢谢!
答案 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
。