3.2 bean 实例化
Spring 中创建 bean 对象时使用 构造方法 来实现的,有三种创建方式
3.2.1 构造方法实例化
1. 示例
package dao;
/**
* @Author 晨默
* @Date 2022/9/29 16:25
*/
public interface BookDao {
public void save();
}
package dao.impl;
import dao.BookDao;
/**
* @Author 晨默
* @Date 2022/9/29 16:39
*/
public class BookDaoImpl implements BookDao {
public BookDaoImpl(){
System.out.println("book dao constructor is running...");
}
public void save(){
System.out.println("book dao save....");
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "#34;>
<beans>
<!-- bean标签标示配置bean
id属性:给bean标示
Class 属性:给bean定义类型
-->
<bean id="bookDao" name="dao" class="dao.impl.BookDaoImpl"/>
<bean id="bookService" name="service service4 bookEbi" class="service.impl.BookServiceImpl">
<!-- 配置 server 与 dao 的关系-->
<!-- property 标签表示配置当前bean的属性
name 属性表示配置哪一个具体的属性
ref 属性表示参照哪一个 bean
-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
import dao.BookDao;
import org.springframework.context.ApplicationContext;
import org. spring framework.context.support.ClassPathXmlApplicationContext;
import service.BookService;
/**
* @Author 晨默
* @Date 2022/9/29 18:56
*/
public class AppForInstanceBook {
public static void main(String[] args) {
// 获取 IOC 容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 从 IOC 容器中获取对象进行方法调用
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
测试结果如下:
由测试结果:说明 Spring容器在创建对象的时候也走的是构造函数
2.将构造函数改成 private 进行测试
package dao.impl;
import dao.BookDao;
/**
* @Author 晨默
* @Date 2022/9/29 16:39
*/
public class BookDaoImpl implements BookDao {
private BookDaoImpl(){
System.out.println("book dao constructor is running...");
}
public void save(){
System.out.println("book dao save....");
}
}
测试结果:
测试结果说明内部走的依然是 构造函数 ,能访问到类中的私有构造方法,显而易见 Spring底层用的是反射
3. 构造函数添加参数测试
package dao.impl;
import dao.BookDao;
/**
* @Author 晨默
* @Date 2022/9/29 16:39
*/
public class BookDaoImpl implements BookDao {
public BookDaoImpl(int i){
System.out.println("book dao constructor is running...");
}
public void save(){
System.out.println("book dao save....");
}
}
运行程序会报错:
说明Spring底层使用的是类的无参数构造方法
3.2.2 静态工厂实例化
1. 工厂方式创建 bean
public interface OrderDao {
public void save();
}
public class OrderDaoImpl implements OrderDao {
public void save(){
System.out.println("order dao save...");
}
}
// 静态工厂创建对象
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
return new OrderDaoImpl();
}
}
public class AppForInstanceOrder {
public static void main(String[] args) {
// 通过静态工厂创建对象
OrderDao orderDao = OrderDaoFactory.getOrderDao();
orderDao.save();
}
}
测试结果:
2. 静态工厂实例化
实现步骤如下:
1. 在 spring 的配置文件 application.xml 中配置
<bean id="orderDao" class="factory.OrderDaoFactory" factory-method="getOrderDao"/>
- class :工厂类的类全名
- factory-mehod :具体工厂类中创建对象的方法名
对应关系如下:
2. 获取 IOC 容器,获取 bean 对象,进行测试
public class AppForInstanceOrder {
public static void main(String[] args) {
/*// 通过静态工厂创建对象
OrderDao orderDao = OrderDaoFactory.getOrderDao();
orderDao.save();*/
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
orderDao.save();
}
}
测试结果如下:
3.2.3 实例工厂与 FactoryBean
1. 环境准备
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save(){
System.out.println("user dao save....");
}
}
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
public class AppForInstanceUser {
public static void main(String[] args) {
// 创建实力工厂对象
UserDaoFactory userDaoFactory = new UserDaoFactory();
// 通过实例工厂创建对象
UserDao userDao = userDaoFactory.getUserDao();
userDao.save();
}
}
测试结果如下:
2. 实例工厂实例化
1. spring 配置文件中添加配置
<!-- 方式三:实力工厂实例化 -->
<bean id="userFactory" class="factory.UserDaoFactory"/>
<bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/>
实例化工厂运行的顺序是:
- 创建实例化工厂对象,对应的是第一行配置
- 调用对象中的方法来创建 bean,对应的是第二行配置
- factory-bean :工厂的实例化对象
- factory-method :工厂对象中的具体创建对象的方法名,对应关系如下:
2. 在 AppForInstanceUser 运行类,使用从 IOC 容器中获取 bean 的方法进行测试
public class AppForInstanceUser {
public static void main(String[] args) {
/*// 创建实力工厂对象
UserDaoFactory userDaoFactory = new UserDaoFactory();
// 通过实例工厂创建对象
UserDao userDao = userDaoFactory.getUserDao();
userDao.save();*/
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
}
}
测试结果如下:
3. FactoryBean 的使用
Spring 为了简化这种配置方式就提供了一种叫 FactoryBean 的方式来简化开发
1. 具体使用步骤
- 创建一个 UserDaoFactoryBean 的类,实现 FactoryBean 接口,重写接口方法
- getObject :在方法中进行对象的创建并返回
- getObjectType :返回被创建的类的 Class 对象
- isSingleton :设置对象是否是单例,默认是否,即不设置单例
public class UserDaoFactoryBean implements FactoryBean {
@Override
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
@Override
public Class<?> getObjectType() {
return UserDao.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
- 在 Spring 的配置文件中进行配置
<bean id="userDao" class="factory.UserDaoFactoryBean"/>
测试结果如下: