在Springs中使用setter注入传递动态参数

时间:2012-02-28 13:51:15

标签: spring

Iam尝试使用spring ioc传递动态参数值,即来自请求的用户名。但是我无法在userdaoimp中看到用户名值。

UserDAOImpl.java

    public class UserDAOImpl implements UserDAO {
    private DataSource dataSource;
    private JdbcTemplate jdbctemplate;
    private String username;


    public void setUsername(String username) {
        this.username = username;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbctemplate =new JdbcTemplate (dataSource);
    }




    public int getUserListSize() {
        System.out.println("UserDAOImpl::getUserListSize()"+username);
        int count=this.jdbctemplate.queryForInt("SELECT COUNT(*) FROM USER_INFO");
        return count;
    }

   }

epis.dao.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-2.5.xsd"> 



    <bean id="userdao" class="com.epis.dao.UserDAO">
        <property name="dataSource">
            <ref local="dataSource" />
        </property>
                <property name="username"/>
    </bean>
</beans>

UserService

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:0)

在XML中,您只能将属性分配给周围的bean。

所以

                 

不起作用,因为UserService没有归档username,因此弹簧不应该启动。

您可以用两种不同的方式编写它:

<bean id="userdao" class="com.epis.dao.UserDAO">
    <property name="dataSource" ref="dataSource" />
    <property name="username" value="aaa"/>
</bean>

<bean  ... class="...UserService">
    <property name="userdao" ref="userdao" />
<bean>

<bean  ... class="...UserService">
    <property name="userdao">
        <bean class="com.epis.dao.UserDAO">
            <property name="dataSource" ref="dataSource" />
            <property name="username" value="aaa"/>
         </bean>
    </property>
<bean>

但是你不能将这两种风格混合在一起。


形成评论

  

实际上我的要求是基于UserService中的其他业务逻辑获取的用户名值。此用户名将被转发到userdao构造函数。如何将该值转发给userdao。

这是不可能的,或者至少没有大量的手写魔法。原因很简单:在应用程序启动时创建XML文件中描述的对象,并在启动时设置值。

但总的来说,我认为你可以通过一些范围内的豆来实现你的目标。但我非常怀疑scoped bean可以用于数据库连接。

我强烈建议您通过在此答案的评论中给出的解释,提出一个关注动态要求的新问题。 (但没有bugy xml示例))

@See Spring Reference Chapter 3.5 Bean scopes

答案 1 :(得分:0)

如果你使username成为UserDaoImpl的属性,那么它不再是线程安全的,即如果两个呼叫同时进入会发生什么?第二次调用将在第一次调用username之前覆盖getUserListSize()属性的设置。您必须为每次调用创建一个新的UserDao对象,这不是非常有效。

最简单的方法是为您的方法使用参数:

所以在UserDao

public int getUserListSize(String username);

UserDaoImpl

public int getUserListSize(String username) {
    logger.debug("UserDAOImpl::getUserListSize():"+username);
    int count = this.jdbctemplate.queryForInt(
        "SELECT COUNT(*) FROM USER_INFO WHERE USER_NAME = ?", username);
    return count;
}

UserService

public int getUserListSize() {
    String username = someBusinessLogicObtainsUsername();
    return this.userDao.getUserListSize(username);
}