经典三层框架初识(二)---Spring 2.2入门案例2补充

咱们前面说的案例,要给UserServiceImpl中的成员属性UserDao赋值,用的是在UserServiceImpl中创建setter方法.然后在配置文件中配置如下的标签

<bean id="userservice" class="service.impl.UserServiceImpl">
	<property name="dao" ref="userdao"></property>
</bean>

注意:<bean>中使用<property>子标签是使用无参构造+setter方法创建我们需要的对象的

但是我们前面还说过,可以使用UserServiceImpl的构造方法来给员属性UserDao赋值.那我们现在看一下:首先我们修改一下UserServiceImpl类的代码:

package service.impl;

import dao.UserDao;
import service.UserService;

public class UserServiceImpl implements UserService {
	
	private UserDao dao;
	//构造器
	public UserServiceImpl(UserDao dao) {
		super();
		this.dao = dao;
	}
	//set方法
      /*public void setDao(UserDao dao) {
		this.dao = dao;
	}*/

	@Override
	public void addUser() {
		dao.addUser();
	}

	@Override
	public void deleteUser() {
		dao.deleteUser();
	}

}

 如果我们不修改配置文件,直接来在原来的测试类Test中运行,那会出现什么情况呢?

这时候会出现下面的异常:没有找到默认的构造器,也就是缺少无参构造

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userservice' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [service.impl.UserServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: service.impl.UserServiceImpl.<init>()

所以我们知道了,如果<bean>中使用<property>字标签是默认调用无参的构造器和setter方法来创建的对象的.那我们这里通过有参构造来实现该适合操作呢? ---我们使用<bean>中的<constructor-arg>这个字标签来实现

<?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="userdao" class="dao.impl.UserDaoImpl"></bean>
	<!-- 测试类中首先要得到一个UserService的实现类对象 我们做如下配置-->
 	<!-- 使用无参构造+setter方法创建对象 -->
	<!-- <bean id="userservice" class="service.impl.UserServiceImpl">
		<property name="dao" ref="userdao"></property>
	</bean> -->
	
	<!-- 使用有参构造 -->
	<bean id="userservice" class="service.impl.UserServiceImpl">
		<!-- 构造器参数: name:参数名称 value:简单类型 ref:引用 
			这里面的name,value,ref和上面的使用setter方法的方式中<property>的属性含义一样 -->
		
		<constructor-arg name = "dao" ref = "userdao"></constructor-arg>
	</bean>
	
</beans>

此时我们在运行,结果就会正常显示"添加用户""删除用户"的正确结果了.除了上面这一种方式,其实还有第二种使用有参构造来创建对象的方法.我们从constructor-arg 这个标签里还发现一些别的东西里面除了name,ref属性之外还有下面两个属性:
       index:参数的索引    第几个参数  从0开始
       type:参数类型的类型 

我们来看一下用法:

<?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="userdao" class="dao.impl.UserDaoImpl"></bean>
	<!-- 测试类中首先要得到一个UserService的实现类对象 我们做如下配置-->
 	<!-- 使用无参构造+setter方法创建对象 -->
	<!-- <bean id="userservice" class="service.impl.UserServiceImpl">
		<property name="dao" ref="userdao"></property>
	</bean> -->
	
	<!-- 使用有参构造 -->
        <bean id="userservice" class="service.impl.UserServiceImpl">
            <constructor-arg index = "0" ref = "userdao"></constructor-arg>
	</bean> -->
	
</beans>

我们构造参数只需要传入一个对象参数,所以种类index的值自然就是0了,我们依旧可以用ref来给这个位于index=0的属性赋值.

为什么需要两种方式呢?其实是因为有些代码不是我们自己写的,咱们在没有源码的情况下调用方法时,方法形式参数的显示的是arg0,arg1..例如下面这样

为了解决这种没有解释不容易辨认的情况.所以给了第二种,哪怕我们不知道参数名字,但是知道位置也可以创建对象.

注意:上面我们通过工厂模式创建的对象都是只有一个成员属性;不管是通过无参构造+setter方法  还是 有参构造 来创建对象,如果成员属性不只一个,那我么只要在配置文件中为每一个属性都配置一个<property>或<constructor-arg>标签即可.2个成员属性就写两个<property>或<constructor-arg>子标签这样.

猜你喜欢

转载自blog.csdn.net/XiaodunLP/article/details/83443787
今日推荐