Spring框架中配置bean的高级属性"props"是啥作用?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架中配置bean的高级属性"props"是啥作用?相关的知识,希望对你有一定的参考价值。

props到底是什么呢?要说键值对应的话,有map了啊,集合的话有list了啊
props和他们有什么区别?

还有
<prop key="insert*">PROPAGATION_REQUIRED</prop>
这句话中"PROPAGATION_REQUIRED"是什么意思?"insert*"是类似于*.do这意思吗?它对应的是一群包含字母"insert"的方法?还是类名?还是什么?

还望各位前辈指教……

给你详细讲一下SSH框架的事物管理,希望对你有帮助。
Struts+hibernate+spring整合开发web应用是相当流行的,只需要简单的配置就能轻松的对数据库进行crud操作,下面就hibernate+spring的配置做一下剖析,一边与大家一起分享经验:

1、 准备工作:

可以利用hibernate tools生成相关映射文件已经po对象、dao对象,dao也可以自己手动编写,无非就是实现crud,如果通过继承hibernate提供的HibernateDaoSupport,则可以更轻松的实现

关键就在于配置文件,下面看一个样例app.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"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--配置数据源-->

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

<!-- 指定连接数据库的驱动 -->

<property name="driverClass" value="com.mysql.jdbc.Driver"/>

<!-- 指定连接数据库的URL -->

<property name="jdbcUrl" value="jdbc:mysql://localhost/auction"/>

<!-- 指定连接数据库的用户名 -->

<property name="user" value="root"/>

<!-- 指定连接数据库的密码 -->

<property name="password" value="root"/>

<!-- 指定连接数据库连接池的最大连接数 -->

<property name="maxPoolSize" value="20"/>

<!-- 指定连接数据库连接池的最小连接数 -->

<property name="minPoolSize" value="1"/>

<!-- 指定连接数据库连接池的初始化连接数 -->

<property name="initialPoolSize" value="1"/>

<!-- 指定连接数据库连接池的连接的最大空闲时间 -->

<property name="maxIdleTime" value="20"/>

</bean>

<!--配置数据库会话工厂-->

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource" ref="dataSource"/>

<property name="mappingResources">

<list>

<value>com/ouya/User.hbm.xml</value>

</list>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>

</props>

</property>

</bean>

<!--配置事务管理器-->

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory"><ref local="sessionFactory"/></property>

</bean>

<!—-配置Spring 事务管理器代理 -->

<bean id="transactionProxyFactory" abstract="true" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager">

<ref local="transactionManager"/>

</property>

<property name="transactionAttributes">

<props>

<prop key="save*">PROPAGATION_REQUIRED</prop>

<prop key="insert*">PROPAGATION_REQUIRED</prop>

<prop key="del*">PROPAGATION_REQUIRED</prop>

<prop key="add*">PROPAGATION_REQUIRED</prop>

<prop key="update*">PROPAGATION_REQUIRED</prop>

<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

<!-- Hibernate模板 -->

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">

<property name="sessionFactory">

<ref local="sessionFactory" />

</property>

</bean>

<!--服务层对象-->

<bean id="us" class="com.ouya.UserService">

<property name="userDao">

<ref local="userDao"/>

</property>

</bean>

<!-- spring代理用户服务对象 -->

<bean id="userService" parent="transactionProxyFactory">

<!-- 如果上面的服务层对象实现了接口,则此处必须设置proxyTargetClass为true,否则会报classcast异常 -->

<!--<property name="proxyTargetClass" value="true"/>-->

<property name="target" ref="us"/>

</bean>

<!-- 用户数据访问对象DATA ACCESS OBJECT -->

<bean id="userDao" class="com.ouya.UserDAO">

<property name="hibernateTemplate" ref="hibernateTemplate"/>

</bean>

</beans>

可以看到配置文件的步骤:

1、 配置数据源

2、 配置会话工厂(依赖注入上面的数据源,还要注入hbm映射文件[注意正确的位置]、hibernate属性文件)

3、 配置事务管理器(依赖注入上面的会话工厂)

4、 Spring中声明事务管理器(根据需要又可分为几种,但都要依赖注入上面的事务管理器,此外还需要配置transationAttributes)

后面的一些普通的bean配置就不用说了

上面的例子中使用的声明事务管理器是:TransactionProxyFactoryBean,这样的话我们就需要在后面配置目标bean,比如上面的例子中我们的原服务对象是id为us的UserService(没有实现接口),所以我们为他配置了id为userService的代理对象(目标bean),程序中使用时只能通过使用代理对象才能实现数据库操作功能(代理对象的父类是上面声明的事务管理器,一边我们使用的时候开启事务),如果直接使用服务对象就无法开启事务

程序中调用:UserService us = (UserService) app.getBean("userService");

注:userService就是上面配置的代理对象的id,而不是原服务对象的id

但是如果我们想通过原服务对象的id来使用对象,则我们需要使用代理事务管理器BeanNameAutoProxyCreator(根据beanname自动代理),上面的配置文件需要做改动,做两件事(当然先要删除原来配置的TransactionProxyFactoryBean,不然就混乱了,可能会报错的):

1、 增加一个事务拦截器

<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">

<property name="transactionManager">

<ref local="transactionManager"/>

</property>

<property name="transactionAttributes">

<props>

<prop key="save*">PROPAGATION_REQUIRED</prop>

<prop key="insert*">PROPAGATION_REQUIRED</prop>

<prop key="del*">PROPAGATION_REQUIRED</prop>

<prop key="add*">PROPAGATION_REQUIRED</prop>

<prop key="update*">PROPAGATION_REQUIRED</prop>

<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="remove*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

2、 定义自动代理事务管理器

<!-- 定义BeanNameAutoProxyCreator-->

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

<!-- 如果服务层对象是接口实现类,则需要设置proxyTargetClass属性为true -->

<!--<property name="proxyTargetClass" value="true"-->

<!-- 指定对满足哪些bean name的bean自动生成业务代理 -->

<property name="beanNames">

<!-- 下面是所有需要自动创建事务代理的bean-->

<list>

<value>us</value>

</list>

<!-- 此处可增加其他需要自动创建事务代理的bean-->

</property>

<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->

<property name="interceptorNames">

<list>

<!-- 此处可增加其他新的Interceptor -->

<value>transactionInterceptor</value>

</list>

</property>

</bean>

然后我们在程序中调用时应如下:

UserService us = (UserService) app.getBean("us");

注:注意与上面使用TransactionProxyFactoryBean时的调用区别,此处我们用getbean时直接取原服务层对象的id,不需要去配置目标bea,这也正是

BeanNameAutoProxyCreator(根据bean名称自动代理)的含义所在

附录:

1、关于hibernate的属性详解:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

<!-- 以下配置都是使用 jdbc.properties 属性文件中的配置,而之所以可以这样写,就是因为有 属性占位符配置的原因 -->

<property name="driverClass" value="$jdbc.driverClassName"/>

<property name="jdbcUrl" value="$jdbc.url"/>

<property name="user" value="$jdbc.username"/>

<property name="password" value="$jdbc.password"/>

<!-- 连接池维持的最小的连接个数 -->

<property name="minPoolSize" value="5"/>

<!-- 连接池维持的最大的连接个数 -->

<property name="maxPoolSize" value="20"/>

<!-- 最大空闲时间, 当某个连接在这个时间内没活动后将从池中移除,前提是池中至少多于最少的连接数: minPoolSize -->

<property name="maxIdleTime" value="1800"/>

<!-- 为加强准备语句的执行性能,此参数指定被缓存的 PreparedStatement 的个数 -->

<property name="maxStatements" value="50"/>

</bean>

Hibernate 会话厂 SessionFactory

Session 就是用于每次与数据库会话的,因此需要:

数据库的配置参数,这些参数就是 上面的数据源指定的! 因此我们只需引用即可: ref="dataSource";

实体映射配置 hibernate.cfg.xml 配置

结果缓存配置(这里使用的是开源的 ehcache)

<!-- Hibernate SessionFactory -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<!-- 引用前面定义的数据源 -->

<property name="dataSource" ref="dataSource"/>

<!-- 所有实体映射文件列表, 所有的 hbm.xml 文件 -->

<property name="mappingResources">

<list>

<value>org/springframework/samples/jpetstore/domain/Account.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Banner.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Category.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Inventory.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Item.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/LineItem.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Order.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Product.hbm.xml</value>

<value>org/springframework/samples/jpetstore/domain/Supplier.hbm.xml</value>

</list>

</property>

<!-- 传统上的 hibernate.cfg.xml 文件的参数放在这里 -->

<property name="hibernateProperties">

<props>

<!-- 指定数据库方言 -->

<prop key="hibernate.dialect">$hibernate.dialect

</prop>

<!-- 是否在日志中输出所有Hibernate与数据库交互的SQL语句 -->

<prop key="hibernate.show_sql">true</prop>

<!-- 是否在日志中输出的SQL 语句格式化成易读形式 -->

<prop key="hibernate.format_sql">true</prop>

<!-- 是否显示统计形式,一般在测试阶段使用 -->

<prop key="hibernate.generate_statistics">true</prop>

<!-- 对于级联查询,一次性获取的级联深度, @todo 需进一步研究 -->

<prop key="hibernate.max_fetch_depth">2</prop>

<!--

Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,一般设置为30、50、100。

Oracle数据库的JDBC驱动默认的Fetch Size=15,设置Fetch Size设置为:30、50,性能会有明显提升,如果继续增大,

超出100,性能提升不明显,反而会消耗内存。

-->

<prop key="hibernate.jdbc.fatch_size">100</prop>

<!--

不必等到累计到50个SQL之后才执行.只要事务commit后,不管缓存中有多少条sql语句都要执行.

hibernate.jdbc.batch_size参数只是设定一次最多可以提交多少sql语句的上限,提高sql语句的执行效率

-->

<prop key="hibernate.jdbc.batch_size">50</prop>

<!--

(1)create 在每次SesstionFactory 构建时(一般是应用重启时,或者伴随着应用服务器重启时),先将之前数据库中的所有数据全

部清空,后紧跟着根据所有的hbm.xml 映射文件重新创建新的数据库表

(2)create-drop 除了create 的所有含义之外,在每次应用的退出前,将进行一次数据空清空。因此这个配置将有两次清空操作,

一次是退出,一次是启动时。

(3)update

如果在开发阶段理发了实体对象的映射文件(hbm.xml) 的定义后,此配置将后台的数据库表进行更新(如增加表的列)

(4)validate

用于校验现有的表与现有的配置是否一致。

-->

<prop key="hibernate.hbm2ddl.auto">update</prop>

<!-- 见下面的解释 -->

<prop key="hibernate.hbm2ddl.auto">update</prop>

<!--结果缓存配置:- 将ehcache.xml 置于 classpath 中- 如果不设置“查询缓存”,

那么hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用findall()、 list()、

Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置

hibernate.cache.use_query_cache true 才行- 在Hbm文件中添加<cache usage="read-only"/>-

如果需要“查询缓存”,还需要在使用Query或Criteria()时设置其setCacheable(true);属性-->

<prop key="hibernate.cache.use_query_cache">true</prop>

<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>

</props>

</property>

<!-- 为解决 merge()方法语义的歧义 @todo 以后进一步解析或者你可以看一下相应的文档 -->

<property name="eventListeners">

<map><entry key="merge">

<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>

</entry></map>

</property>

</bean>

2、Spring的transactionAttributes

PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
参考技术A PROPAGATION_REQUIRED意思是支持当前事务,如果当前没有事务,就新建一个事务。
insert*意思是对所有以insert开头的方法应用事务控制。
list, set, map和props元素分别用来设置类型为List,Set,Map和Propertis的属性值,分别用来为bean传入集合值
参考技术B

知道上很多答案都是乱答,复制粘贴的人很恶心。很多采纳的答案都是错的。

    回答你第一个问题,引入键值对

<property name="xxx">
    <prop key="insert*">PROPAGATION_REQUIRED</prop>
    <prop key="xxx">XXXX</prop>
    等等
</property>

key是键,prop标签中间是值。

等价于:

<property name="xxx">
    <value>
        键1=值1
        键2=值2
        等等
    </value>
</property>

你还可以配置外部properties文件,用context标签引入:

<congtext:property-placeholder location="classpath:你的properties路径" />

    回答你第二个问题

    PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。是事物传播行为的一种(还有其他的六种),具体可以再百度。
    insert* 是执行insert开头(因为你后面跟了*)的方法时的事物如何处理。

手敲的原创回答,你找不到其他出处的。

spring-高级依赖关系配置

1、关于配置文件一些使用

     组件与组件之间的耦合,采用依赖注入管理;基本类型的成员变量值,应该直接在代码中设置。

2、获取其他bean的属性值

   PorpertyPathFactoryBean用来获取目标bean的属性值(实际上就是它的getter方法的返回值),获得的值可以注入给其他bean,也可以直接定义成新的bean。使用PorpertyPathFactoryBean来调用其他bean的getter方法需要指定如下信息:

       调用哪个对象:由PorpertyPathFactoryBean的setTargetObject(Object targetObject)的方法指定。

       调用哪个getter方法:由PorpertyPathFactoryBean的setPropertyPath(String propertyPath)方法指定。

       举个例子:

       技术图片

        Person.java

package com.lfy.bean;

public class Person 
  
    private int age;
    private Son son;
    
    public Son getSon() 
        return son;
    
    public void setSon(Son son) 
        this.son = son;
    
    public int getAge() 
        return age;
    
    public void setAge(int age) 
        this.age = age;
    

       Son.java

package com.lfy.bean;

public class Son 

    private int age;

    public int getAge() 
        return age;
    

    public void setAge(int age) 
        this.age = age;
    
    
    @Override
    public String toString() 
        return "Son[age="+age+"]";
    

       beans.xml

<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    
    <!--下面配置定义一个将要被引用的目标bean-->
    <bean id="person" class="com.lfy.bean.Person">
        <property name="age" value="30"/>
        <property name="son">
            <!-- 使用嵌套Bean定义setSon()方法的参数值 -->
            <bean class="com.lfy.bean.Son">
                <property name="age" value="11" />
            </bean>
        </property>
    </bean>

    <!-- 将指定Bean实例的getter方法返回值定义成son1 Bean -->
    <bean id="son1" class=
        "org.springframework.beans.factory.config.PropertyPathFactoryBean">
        <!-- 确定目标Bean,指定son1 Bean来自哪个Bean的getter方法 -->
        <property name="targetBeanName" value="person"/>
        <!-- 指定son1 Bean来自目标bean的哪个getter方法,son代表getSon() -->
        <property name="propertyPath" value="son"/>
    </bean>
    
    <!-- 下面定义son2 Bean -->
    <bean id="son2" class="com.lfy.bean.Son">
        <property name="age">
            <!-- 使用嵌套Bean为调用setAge()方法指定参数值 -->
            <!-- 以下是访问指定Bean的getter方法的简单方式, 
            person.son.age代表获取person.getSon().getAge()-->
            <bean id="person.son.age" class=
                "org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
        </property>
    </bean>
    
    <!-- 将基本数据类型的属性值定义成Bean实例 -->
    <bean id="theAge" class=
        "org.springframework.beans.factory.config.PropertyPathFactoryBean">
        <!-- 确定目标Bean,表明theAge Bean来自哪个Bean的getter方法的返回值 -->
        <property name="targetBeanName" value="person"/>
        <!-- 使用复合属性来指定getter方法。son.age代表getSon().getAge() -->
        <property name="propertyPath" value="son.age"/>
    </bean>
    
    <!-- 将基本数据类型的属性值定义成Bean实例 -->
    <bean id="theAge2" class=
        "org.springframework.beans.factory.config.PropertyPathFactoryBean">
        <!-- 确定目标Bean,表明theAge2 Bean来自哪个Bean的属性。
            此处采用嵌套Bean定义目标Bean -->
        <property name="targetObject">
            <!-- 目标Bean不是容器中已经存在的Bean, 而是如下的嵌套Bean-->
            <bean class="com.lfy.bean.Person">
                <property name="age" value="30"/>
            </bean>
        </property>
        <!-- 指定theAge2 Bean来自目标bean的哪个getter方法,age代表getAge() -->
        <property name="propertyPath" value="age"/>
    </bean>
    
    <!-- son1的简化配置  -->
    <util:property-path id="son3" path="person.son"/> 
    
    <!-- son2的简化配置  -->
    <bean id="son4" class="com.lfy.bean.Son">
        <property name="age">
            <util:property-path path="person.son.age"/>
        </property>
    </bean>
    
    <!-- theAge的简化配置  -->
    <util:property-path id="theAge3" path="person.son.age"/>
</beans>

      SpringTest.java

package com.lfy.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lfy.bean.Person;

/**
 * 
 * @author lfy
 *
 */
public class SpringTest 

    public static void main(String[] args) 
        //创建spring容器
        ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
        System.out.println("系统获取son1:"+ctx.getBean("son1"));
        System.out.println("系统获取son2:"+ctx.getBean("son2"));
        System.out.println("系统获取theAge:"+ctx.getBean("theAge"));
        System.out.println("系统获取theAge:"+ctx.getBean("theAge2"));
        //简化配置
        System.out.println("系统获取son3:"+ctx.getBean("son3"));
        System.out.println("系统获取son4:"+ctx.getBean("son4"));
        System.out.println("系统获取theAge3:"+ctx.getBean("theAge3"));
    

     运行结果:

技术图片

    总结:<util:property-path.../>元素可以作为PropertyPathFactoryBean的简化配置,需要使用该元素,必须在配置文件中声明util:命名空间。其配置时指定的两个属性

     id:该属性指定将getter方法的返回值定义成名为id的bean实例,如本例的son3。

     path:该属性指定将哪个bean实例、哪个属性(可以是复合属性)暴露出来。

3、获取Field字段值

    FieldRetrievingFactoryBean,可以访问类的静态Field或对象的实例Field值。使用FieldRetrievingFactoryBean访问Field分两种情形:

      1》要访问的Field是静态Field,需要指定

            调用哪个类:由FieldRetrievingFactoryBean的setTargetClass(String targetClass)方法指定。

            访问哪个Field:由FieldRetrievingFactoryBean的setTargetField(String targetField)方法指定。

      2》要访问的Filed是实例Field(要求实例的Field使用public控制访问权限,没太大用处),需要指定  

            调用哪个对象:由FieldRetrievingFactoryBean的setTargetObject(String targetObject)方法指定。

            访问哪个Field:由FieldRetrievingFactoryBean的setTargetField(String targetField)方法指定。

4、获取方法返回值

    MethodInvokingFactoryBean工厂bean,使用MethodInvokingFactoryBean两种情形:

      1》要访问的是静态方法,需要指定

            调用哪个类:由MethodInvokingFactoryBean的setTargetClass(String targetClass)方法指定。

            调用哪个方法:由MethodInvokingFactoryBean的setTargetMethod(String targetMethod)方法指定。

            调用方法的参数:由MethodInvokingFactoryBean的setTargetArguments(Object[] arguments)方法指定。方法无参数该配置可以省略。

      2》要访问的是实例方法,需要指定  

            调用哪个对象:由MethodInvokingFactoryBean的setTargetObject(Object targetObject)方法指定。

            调用哪个方法:由MethodInvokingFactoryBean的setTargetMethod(String targetMethod)方法指定。

            调用方法的参数:由MethodInvokingFactoryBean的setTargetArguments(Object[] arguments)方法指定。方法无参数该配置可以省略。

以上是关于Spring框架中配置bean的高级属性"props"是啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

Error creating bean with name " "问题

Spring框架bean的配置:SpEL:引用 Bean属性和方法。。。

Spring_总结_04_高级配置_运行时注入值

spring-高级依赖关系配置

Spring框架学习[IoC容器高级特性]

Spring框架学习笔记——配置bean