环境准备
- 创建一个Maven项目。
- pom.xml中添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
- resources添加Spring配置文件applicationContext.xml
构造方法实例化
- 装备需要杯创建的类
准备一个BookDao和BookDaoImpl类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
- 将类配置到Spring容器中
<?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="inheima.dao.impl.BookDaoImpl"/>
</beans>
- 编写运行程序
public static void main(String[] args) {
ApplicationContext c = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao=(BookDao) c.getBean("bookDao");
bookDao.save();
}
运行结果
book dao save ...
- 类中提供构造函数测试
public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("book dao constructor is running ...");
}
public void save() {
System.out.println("book dao save ...");
}
}
运行程序,如果控制台有打印构造函数中的输出,说明Spring容器在创建对象的时候也走的式构造函数
输出结果:
book dao constructor is running ...
book dao save ...
- 将构造函数改成private测试
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底层用的式反射
运行结果:
book dao constructor is running ...
book dao save ...
- 构造函数添加一个参数测试
public class BookDaoImpl implements BookDao {
private BookDaoImpl( int i) {
System.out.println("book dao constructor is running ...");
}
public void save() {
System.out.println("book dao save ...");
}
}
运行程序报错,说明Spring底层使用的式类的无参构造方法。
二、静态工厂实例化
- 工厂方式创建bean
准备一个OrderDao和OrderDaoImpl类
public interface OrderDao {
public void save();
}
public class OrderDaoImpl implements OrderDao {
public void save(){
System.out.println("order dao save ...");
}
}
- 创建一个工厂类OrderDaoFactory并提供一个静态方法
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
System.out.println("factory setuo ...");
return new OrderDaoImpl();
}
}
- 在spring配置文件中添加一下内容
<bean id="orderDao" class="inheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
- 编写AppForInstanceOrder运行类,在类中通过工厂获取对象
public class AppForIntanceOrder {
public static void main(String[] args) {
ApplicationContext c= new ClassPathXmlApplicationContext("applycationContext.xml");
OrderDao orderDao= (OrderDao) c.getBean("orderDao");
orderDao.save();
}
}
运行结果为:
oeder dao save ...
三、实例工厂与FactoryBean
- 准备一个UserDao和UserDaoImpl
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("user dao save ...");
}
}
- 创建一个工厂类OrderDaoFactory并提供一个普通方法,此处和静态工厂的工厂类不一样的地方式方法不是静态方法。
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
- 在spring的配置文件中添加一下内容
<bean id="userFactory" class="inheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
实例化工厂运行的顺序是:
- 创建实例化工厂对象,对应的是第一行配置。
- 调用对象中的方法创建bean,对应的是第二行配置
factory-bean:工厂的实例对象。
factory-method:工厂对象中的具体创建对象的方法名。
- 在AppForInstanceUser运行类,使用IOC容器获取bean的方法进行运行
public class AppForIntanceUser {
public static void main(String[] args) {
ApplicationContext c=new ClassPathXmlApplicationContext("applycationContext.xml");
UserDao userDao= (UserDao) c.getBean("userDao");
userDao.save();
}
}
- 运行结果:
user dao save ...
FactoryBean的使用
- 创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
@Override
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
@Override
public Class<?> getObjectType() {
return UserDao.class;
}
}
- 在spring文件中进行配置
<bean id="userDao" class="inheima.factory.UserDaoFactoryBean"/>
- AppForInstanceUser运行类不用做修改,直接运行,结果如下:
user dao save ...
这种方式在Spring去整合其他框架的时候会被用到,所以这种方式需要大家理解掌握。
查看源码会发现,FactoryBean接口其实会有三个方法,分别是:
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() {
6return true;
}