Spring入门—Bean相关知识
文章目录
1 Bean的配置
1.1 为bean配置别名
只需要在配置文件里引入name属性,name里面的别名可以有多个,中间使用空格 逗号 分号分割都可以
<?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="BookDao" class="com.demo.dao.impl.BookDaoImpl"></bean>
<bean id="BookService" name="service service2 service3" class="com.demo.service.impl.BookServiceImpl">
<property name="bookDao" ref="BookDao"></property>
</bean>
</beans>
配置好后,调用service2,查看运行结果
1.2 Bean的作用范围
控制bean创建的时候,对象是否为单例的
运行以下代码,看一下这两个对象的地址是不是一样的,看看是不是同一个对象。运行结果为地址相同,说明spring默认给我们创建的bean是单例的
如何配置非单例的,在配置文件中,加入scope属性。有两个选项,分别是:propertype(非单例) singleton(单例),默认为单例
将属性设置为propertype后,再次运行,发现创建的对象是两个了
哪些bean适合单例
- 表现层对象(servelet)
- 业务层对象(service)
- 数据层对象(dao)
- 工具对象
不适合单例
- 封装实体的域对象(domain)
2 Bean的实例化
2.1 构造方法
无参构造
在BookDao的实现类中,为其创建无参构造函数,先设置为public,发现构造函数执行了
再设置为private,发现构造函数也执行了
静态工厂
创建一个工厂类
配置xml时,class配置的是工厂类名
<?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="OrderDao" class="com.demo.factory.OrderDaofactory" factory-method="getOrderDao"></bean> </beans>
创建对象测试一下
实例工厂
有了实例工厂类之后,就要先创建对象再去引用
实例工厂
public class UserDaofactory {
public UserDao getUserDao() {
return new UserDaoImpl();
}
}
启动类
import com.demo.dao.UserDao;
import com.demo.factory.UserDaofactory;
public class AppForInstanceUser {
public static void main(String[] args) {
//创建实例工厂对象
UserDaofactory userDaofactory = new UserDaofactory();
//通过实例工厂对象创建对象
UserDao userDao = userDaofactory.getUserDao();
userDao.test();
}
}
如何使用这个方法
配置文件改为
<bean id="userFactory" class="com.demo.factory.UserDaofactory"></bean> <bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"></bean>
运行结果
这种方法的改良
创建一个FactoryBean类
并且让这个类继承FactoryBean这个接口
配置xml,class指向FactoryBean
<!-- 改良的方法配置-->
<bean id="userDao" class="com.demo.factory.UserDaoFactoryBean"></bean>
3 Bean的生命周期
生命周期
从创建到消亡的完整过程
bean生命周期
bean从创建到销毁的整体过程
bean生命周期控制
在bean创建后到销毁前做的一些事情
- 在dao的实现类里创建初始化函数和销毁函数
import com.demo.dao.BookDao;
public class BookDaoImpl implements BookDao {
@Override
public void test() {
System.out.println("BookDao is running...");
}
//bean初始化对应的操作
public void init() {
System.out.println("init...");
}
//bean销毁前对应的操作
public void destory() {
System.out.println("destory...");
}
}
- 在配置文件中声明初始化函数和销毁函数
<bean id="BookDao" class="com.demo.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"></bean>
- 运行。发现只执行了init
如何运行destory函数
先将ApplicationContext applicationContext改为ClassPathXmlApplicationContext
注册关闭钩子
applicationContext.registerShutdownHook();
暴力关闭
applicationContext.close();
按照spring接口的方式实现bean的生命周期
本次操作在service层操作
- 在实现类里继承InitializingBean, DisposableBean两个接口,并且实现destroy()和afterPropertiesSet()两个方法
- 运行
为什么继承的接口实现初始化的方法不叫init,而是叫做set之后
在set的函数里写上输出内容,执行一下
import com.demo.dao.BookDao;
import com.demo.dao.impl.BookDaoImpl;
import com.demo.service.BookService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
//删除业务层中使用new的方式创建到对象
private BookDao bookDao;
@Override
public void test() {
System.out.println("BookService is running...");
bookDao.test();
}
//提供对应的set方法
public void setBookDao(BookDao bookDao) {
System.out.println("set...");
this.bookDao = bookDao;
}
@Override
public void destroy() throws Exception {
System.out.println("Service destory...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Service init...");
}
}
总结
bean的生命周期
- 初始化容器
- 创建对象(分配内存)
- 执行构造方法
- 执行属性注入(set操作)
- 执行bean的初始化方法
- 使用bean
- 执行业务操作
- 关闭/销毁容器
- 执行bean销毁方法