Ioc
控制反转IoC,一种设计思想,是spring的核心。所谓IoC,就是Spring来负责控制对象的生命周期和对象间的关系。类在spring容器中登记后,告诉spring你需要什么类,然后spring会把你需要的类给你,同时spring也会在别的类需要你的时候把你交给它。
DI
依赖注入,是实现控制反转的一种方法
●谁依赖于谁:当然是应⽤程序依赖于IoC容器;
●为什么需要依赖:应⽤程序需要IoC容器来提供对象需要的外部资源;
●谁注⼊谁:很明显是IoC容器注⼊应⽤程序某个对象,应⽤程序依赖的对象;
●注⼊了什么:就是注⼊某个对象所需要的外部资源(包括对象、资源、常量数据)。
运用IoC解决程序解耦
1.编写业务层接口和实体类
//接口
public interface IAccountService {
//保存账户(此处只是模拟,并不是真的要保存)
void saveAccount();
}
//实现类
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao = new AccountDaoImpl();//此处的依赖关系有待解决
public void saveAccount() {
accountDao.saveAccount();
}
}
2.创建持久层和实体类
//接口
public interface IAccountDao {
//保存账户
void saveAccount();
}
//实现类
public class AccountDaoImpl implements IAccountDao {
public void saveAccount() {
System.out.println("保存了账户");
}
}
3.让spring管理资源,在配置文件中配置service和dao
<!-- bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中 id 属性:对象的唯一标识。 class 属性:指定要创建对象的全限定类名-->
<!-- 配置 service -->
<bean id="accountService" class="com.zx.service.impl.AccountServiceImpl">
</bean>
<!-- 配置 dao -->
<bean id="accountDao" class="com.zx.dao.impl.AccountDaoImpl">
</bean>
4.测试配置的主函数
public static void main(String[] args) {
//1.使用 ApplicationContext 接口,就是在获取 spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据 bean 的 id 获取对象
IAccountService aService = (IAccountService) ac.getBean("accountService");
System.out.println(aService);
IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");
System.out.println(aDao);
spring工厂结构图
BeanFactory和ApplicationContext的区别
BeanFactory 才是 Spring 容器中的顶层接口。
ApplicationContext 是它的子接口。
BeanFactory 和 ApplicationContext 的区别:
创建对象的时间点不一样。 ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。 BeanFactory:什么使用什么时候创建对象。
ApplicationContext 接口的实现类
ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件---------------推荐使用这种
FileSystemXmlApplicationContext:它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
AnnotationConfigApplicationContext: 当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
Bean标签和管理对象的细节
Bean标签
- 作用:
用于配置对象让 spring 来创建的。 默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。 - 属性:
id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
init-method:指定类中的初始化方法名称。
destroy-method:指定类中销毁方法名称。
scope:指定对象的作用范围:- singleton :默认值,单例的.
- prototype :多例的.
- request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
Bean的作用范围和生命周期:
- 单例对象:scope="singleton"
一个应用只有一个对象的实例。它的作用范围就是整个引用。 生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。 对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。 多例对象:scope="prototype"
每次访问对象时,都会重新创建对象实例。 生命周期:
对象出生:当使用对象时,创建新的对象实例。 对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。实例化Bean的三种方式
- 第一种方式:使用默认无参构造函数
<!--在默认情况下:
它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。-->
<bean id="accountService" class="com.zx.service.impl.AccountServiceImpl"/>
- 第二种方式:spring管理静态工厂-使用静态工厂的方法创建对象
// 模拟一个静态工厂,创建业务层实现类
public class StaticFactory {
public static IAccountService createAccountService(){
return new AccountServiceImpl();
}
}
<!-- 此种方式是: 使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定静态工厂的全限定类名
factory-method 属性:指定生产对象的静态方法
-->
<bean id="accountService" class="com.zx.factory.StaticFactory" factory-method="createAccountService"></bean>
- 第三种方式:spring管理实例工厂-使用实例工厂的方法创建对象
//模拟一个实例工厂,创建业务层实现类
//此工厂创建对象,必须现有工厂实例对象,再调用方法
public class InstanceFactory {
public IAccountService createAccountService(){
return new AccountServiceImpl();
}
}
<!-- 此种方式是:
先把工厂的创建交给 spring 来管理。 然后在使用工厂的 bean 来调用里面的方法
factory-bean 属性:用于指定实例工厂 bean 的 id。
factory-method 属性:用于指定实例工厂中创建对象的方法。
-->
<bean id="instancFactory" class="com.zx.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instancFactory" factory-method="createAccountService"></bean>
依赖注入
- 使用构造函数的方式,给 service 中的属性传值
要求:
类中需要提供一个对应参数列表的构造函数。
涉及的:
标签: constructor-arg
属性:
index:指定参数在构造函数参数列表的索引位置
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称 用这个找给谁赋值
=======上面三个都是找给谁赋值,下面两个指的是赋什么值的==============
value:它能赋的值是基本数据类型和 String 类型
ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
- 通过配置文件给 bean 中的属性传值,使用 set 方法的方式
涉及的:
标签: property
属性:
name:找的是类中set 方法后面的部分
ref:给属性赋值是其他 bean 类型的
value:给属性赋值是基本数据类型和 string 类型的
实际开发中,此种方式用的较多。