一、bean最常见的scope:
singleton:默认的,单例
prototype:每调⽤⼀次getBean()⽅法则获取⼀个新的Bean对象。即每次注⼊的时候都是新对象
对象的创建时期有所区别:
1、singleton在获取上下文,getBean()获取对象之前就已经创建完毕。
在无参构造方法里给出已经创建完毕的提示:
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
public class userDaoImpl2 implements UserDao {
public userDaoImpl2() {
System.out.println("bean已经成功创建");
}
@Override
public void save() {
}
}
xml配置文件:
<bean id="myuerDaoImpl2" class="com.itheima.dao.impl.userDaoImpl2"></bean>
运行将getbean()注释掉的代码,测试:
@Test
//测试scope属性
public void test(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("exercize.xml");
// userDaoImpl2 userDaoImpl2 = applicationContext.getBean("myuerDaoImpl2",userDaoImpl2.class );
// System.out.println(userDaoImpl2);
}
测试结果:
2、prototype 在去获取bean对象时,ioc容器才进行创建
将上面的xml文件里scope改成prototype,其他不变:
<bean id="myuerDaoImpl2"
class="com.itheima.dao.impl.userDaoImpl2"
scope="prototype"></bean>
测试结果:
可以看到在初始化spring上下文的时候并没有创建bean对象
把getbean()打开的运行结果:
@Test
//测试scope属性
public void test(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("exercize.xml");
userDaoImpl2 userDaoImpl2 = applicationContext.getBean("myuerDaoImpl2",userDaoImpl2.class );
System.out.println(userDaoImpl2);
}
二、基于xml的自动装配
1、autowire=“byType”
需要提供setXXX方法。
2、autowire=“byName”
需要提供setXXX方法,同时XXX必须和xml配置文件里bean的 id 名字相同。setAge() 对应的名字是age,setPassword()对应的名字是password。
DAO实现类:
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
public class userDaoImpl2 implements UserDao {
@Override
public void save() {
System.out.println("正在保存数据");
}
}
Service层:
package com.itheima.service.impl;
import com.itheima.dao.UserDao;
import com.itheima.dao.impl.userDaoImpl2;
import com.itheima.service.UserService;
public class UserServiceImpl2 implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
而假设xml里:
<bean id="myuerDaoImpl2" class="com.itheima.dao.impl.userDaoImpl2" scope="prototype"></bean>
<bean id="myUserServiceImpl2" class="com.itheima.service.impl.UserServiceImpl2" autowire="byName"></bean>
测试:
@Test
//测试scope属性
public void test(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("exercize.xml");
UserServiceImpl2 userServiceImpl2 = applicationContext.getBean("myUserServiceImpl2", UserServiceImpl2.class);
userServiceImpl2.save();
}
测试结果:
空指针异常在于无法找到这个id叫userDao的对象,解决办法:将setUserDao改成xml里bean的id,或者将id改成userDao
Service层:
public class UserServiceImpl2 implements UserService {
private UserDao userDao;
public void setMyuerDaoImpl2(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
再次运行测试,结果:
3、autowire=“constructor”
只需要提供有参构造方法。
<bean id="myuerDaoImpl2" class="com.itheima.dao.impl.userDaoImpl2" scope="prototype"></bean>
<bean id="myUserServiceImpl2" class="com.itheima.service.impl.UserServiceImpl2" autowire="constructor"></bean>
Service层:
public class UserServiceImpl2 implements UserService {
private UserDao userDao;
// public void setMyuerDaoImpl2(UserDao userDao) {
// this.userDao = userDao;
// }
@Override
public void save() {
userDao.save();
}
public UserServiceImpl2(UserDao userDao) {
this.userDao = userDao;
}
}
再次运行测试,结果: