What is happening inside applicationContext.xml

2019-08-18 02:28发布

Will someone please explain what the following applicationContext.xml file is doing? For greater context, I get it from http://persistentdesigns.com/wp/jersey-spring-and-jpa/.

Some of my questions (not exhaustive, since I really don't understand much):

  • For id="dataSource" is dataSource a keyword or is it the name of the datasource I am to use? For example, if the name of my datasource is actuall learningRestDS, do I replace dataSource with learningRestDS?

  • Why is the datasource class name org.springframework.jdbc.datasource.DriverManagerDataSource instead of com.mysql.jdbc.jdbc2.optional.MysqlDataSource?

applicationConext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
   <!--  Scan for both Jersey Rest Annotations a -->
   <context:component-scan base-package="com.persistent.rest,com.persistent.service,com.persistent.service.jpa"/>
   <context:annotation-config />
   <tx:annotation-driven />
   <bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"
    p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/jpa"
    p:username="user" p:password="password" />

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
    <property name="loadTimeWeaver">
        <bean
            class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    </property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
    p:entityManagerFactory-ref="entityManagerFactory" />
<bean id="jpaAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    p:database="MYSQL" p:showSql="true" />

UPDATE: ERROR:

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService':
Injection of persistence methods failed;
nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'entityManagerFactory' defined in class path resource [applicationContext.xml]:
Invocation of init method failed; nested exception is java.lang.AbstractMethodError: 
org.springframework.orm.jpa.persistenceunit.SpringPersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode;

2条回答
Root(大扎)
2楼-- · 2019-08-18 03:10

"dataSource" is an arbitrary bean name (ID) you use later to reference that bean:

p:dataSource-ref="dataSource"

If your data source was named "learningRestDS" you would use:

p:dataSource-ref="learningRestDS"

The p:dataSource-ref is the name of the property of DriverManagerDataSource (you'll find setDataSource() method on that class that will be used to inject learningRestDS.


When defining a data source you are free to use any class that implements DataSource interface (the power of abstraction). The author of this XML chose to use DriverManagerDataSource instead of MysqlDataSource. They will work just as good1 as long as they both follow the DataSource contract.

There are many other possible implementations of DataSource, e.g. and connection pooling libraries. The advantage of them is that they work with all JDBC drivers/databases.

1 actually DriverManagerDataSource should only be used for testing as it performs very poorly, but from functional perspective, it's as good as any other DataSource.


UPDATE to answer your comments. You are seeing:

Invalid property 'driverClassName' of bean class [com.mysql.jdbc.jdbc2.optional.MysqlDataSource]: No property 'driverClassName' found 

which means Spring tries to inject something to property driverClassName of MysqlDataSource - which doesn't have such property (setter). This also means that the application context XML file you are quoting is incomplete/inconsistent/incorrect as according to you it uses DriverManagerDataSource. Make sure this is the file Spring uses and remove driverClassName property if MySQL data source is used.

查看更多
Juvenile、少年°
3楼-- · 2019-08-18 03:11

The id of "dataSource" is just a name that the Java bean instance is associated with. You can change it to anything that you want, just as long as you also update any ref="" attributes that point to it.

The class org.springframework.jdbc.datasource.DriverManagerDataSource is a helper class that encapsulates all of the code normally associated with manually instantiating a JDBC connection. So in that sense you can think of it as a wrapper. It takes the properties you supply, namely the driver class and url, and uses that to instantiate new connections.

That being said, as long as com.mysql.jdbc.jdbc2.optional.MysqlDataSource implements the java.sql.DataSource interface you could use that as a drop in replacement.

In a production environment you will likely replace that with a pooling data source, or even a JNDI configured connection pool. There are a lot of choices, you aren't stuck with only using Spring's DriverManagerDataSource.

查看更多
登录 后发表回答