IoC的概念
控制反转(Inversion of Controller),把创建对象的权利交给框架或工厂。它包括依赖注入(DI)和依赖查找。就是把创建对象的过程交给spring框架,开发者只关注对象的使用,不关注对象创建过程。
IoC的主要作用
解决程序间代码的耦合。
spring 的开发包
jar包官网下载地址: JFroghttps://repo.spring.io/ui/repos/tree/General/libs-release-local/org/springframework spring核心包的maven坐标
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.20.RELEASE</version>
</dependency>
</dependencies>
spring基于xml的IoC演示示例
1.创建两个需要spring管理的bean
package org.example.service;
public class AccountService {
public void run() {
System.out.println("我是处理业务的。。。。");
}
}
package org.example.dao;
public class AccountDao {
public void run() {
System.out.println("我是查数据库的。。。。");
}
}
2.创建bean的管理配置文件,配置bean
<?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">
<!-- id:需要spring管理的bean的唯一标识,class:bean的类路径-->
<bean id="accountService" class="org.example.service.AccountService"></bean>
<bean id="acountDao" class="org.example.dao.AccountDao"></bean>
</beans>
3.调用测试
ApplicationContext加载对象管理测试
package org.example;
import org.example.dao.AccountDao;
import org.example.service.AccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
//获取核心容器,入参为bean配置文件的路径和文件名
ApplicationContext ac = new ClassPathXmlApplicationContext("springBean.xml");
//根据id获取bean对象
AccountService accountService = (AccountService) ac.getBean("accountService");
AccountDao acountDao = (AccountDao) ac.getBean("acountDao");
//对象调用测试
accountService.run();
acountDao.run();
}
}
BeanFactory 加载对象管理测试
public class Main {
public static void main(String[] args) {
//获取对象配置文件
Resource resource = new ClassPathResource("springBean.xml");
//加载对象配置文件
BeanFactory factory = new XmlBeanFactory(resource);
//根据id获取bean对象
AccountService accountService = (AccountService) factory.getBean("accountService");
AccountDao acountDao = (AccountDao) factory.getBean("acountDao");
//对象调用测试
accountService.run();
acountDao.run();
}
}
ApplicationContext 和 BeanFactory 的区别
ApplicationContext:适用单例对象,构建核心容器时采用的策略是立即加载,读取完配置文件就马上创建配置文件中所有的配置的对象。
BeanFactory :适用多例对象,延迟加载方式,在获取对象被使用对象时创建对象。
ApplicationContext 的三个常用实现类
- ClassPathXmlApplicationContext : 加载类路径下的配置文件
- FileSystemXmlApplicationContext : 加载磁盘任意路径下的配置文件(需要有访问权限)
- AnnotationConfigApplicationContext : 读取注解创建容器
spring管理bean的细节
spring创建bean的三种方式
1.在spring配置文件的bean标签只配置了id和class,spring采用默认构造器创建bean对象,如果没有默认构造器,则创建失败。
2.使用某个类中的方法或者工厂方法创建对象,并存入spring容器
代码示例:
··· a.创建一个工厂方法
public class FactoryService {
public AccountService getBean(){
//返回没有默认构造器的类对象
return new AccountService(true);
}
}
b.修改配置
<!-- <bean id="accountService" class="org.example.service.AccountService"></bean>-->
<!-- spring配置工厂类的管理配置-->
<bean id="factoryService" class="org.example.service.FactoryService"></bean>
<!-- 指定对像需要怎么创建 factory-bean:被spring管理的工厂bean的ID,factory-method:工厂对象中返回需要spring管理的对象的方法名-->
<bean id="accountService" factory-bean="factoryService" factory-method="getBean"></bean>
c.调用示例
public class Main {
public static void main(String[] args) {
//获取核心容器,入参为bean配置文件的路径和文件名
ApplicationContext ac = new ClassPathXmlApplicationContext("springBean.xml");
//根据id获取bean对象
AccountService accountService = (AccountService) ac.getBean("accountService");
//对象调用测试
accountService.run();
}
}
3.使用工厂中的静态方法创建对象
a.创建静态工厂方法
public class FactoryService {
public static AccountService getBean(){
//返回没有默认构造器的类对象
return new AccountService(true);
}
}
b.修改配置文件
<!-- class 指向工厂类,factory-method 获取对象的工厂方法-->
<bean id="accountService" class="org.example.service.FactoryService" factory-method="getBean"></bean>
bean对象的作用范围
bean标签的 scope属性指定bean的作用范围
- singleton :单例,默认
- prototype : 多例
- request :作用于web请求
- session : 作用于web的会话范
- global-session :作用于集群环境的会话范围
<bean id="acountDao" class="org.example.dao.AccountDao" scope="singleton"></bean>
bean对象的生命周期
单例对象:当容器创建时,创建对象,容器在对象就一直在,容器销毁时对象消亡
多例对象:获取对象是框架创建对象,使用完成后,且没有别的对象引用,由java的垃圾回收器回收。
DI依赖注入 Dependenct Injection
概念: IOC的作用通过配置依赖关系降低程序间的耦合,依赖关系的管理:以后都交给spring来维护,在当前类需要用到其他类对象时,由spring给我们提供,我们只需要在配置文件中说明,依赖关系的维护就是依赖注入。
能注入的数据类型:
1.基本类型和String,使用构造函数提供
2.其他bean类型,使用set方法提供
3.复杂类型/集合类型,使用注解提供
构造函数注入:
标签:constructor-arg
标签位置:bean 标签的子标签
标签的属性:
type:用于指定要注入数据的数据类型,和构造函数中的数据类型要一致
index:用于给构造函数中指定位数的参数赋值,索引位置从0开始
name:用于给构造函数中指定名称参数赋值,名称和构造函数中名称一致(常用)
value:用于给基本数据类型和String类型赋值
ref:用于指定对象类型参数赋值
优势:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功
弊端:改变了bean对象实例化方式,使我们在创建对象时如果用不到这些数据也必须提供
经常变化的数据不适用注入的方式。
代码示例
1.创建bean对象类,重载构造函数
public class AccountService {
private String name;//String类型
private int age;//基本数据类型
private Date birthdy;//对象类型
public AccountService(String name, int age, Date birthdy) {
this.name = name;
this.age = age;
this.birthdy = birthdy;
}
public void run() {
System.out.println("对象创建成功name=" + name + ";age=" + age + ";birthdy=" + birthdy);
}
}
2.配置bean 注入
<?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="timeObject" class="java.util.Date"></bean>
<bean id="accountService" class="org.example.service.AccountService">
<constructor-arg name="name" value="哈哈哈"></constructor-arg>
<constructor-arg name="age" value="30" ></constructor-arg>
<!-- ref 对象类型,引用其他bean,值为其他bean的ID-->
<constructor-arg name="birthdy" ref="timeObject"></constructor-arg>
</bean>
</beans>
3.调用示例
public class Main {
public static void main(String[] args) {
//获取对象配置文件
Resource resource = new ClassPathResource("springBean.xml");
//加载对象配置文件
BeanFactory factory = new XmlBeanFactory(resource);
//根据id获取bean对象
AccountService accountService = (AccountService) factory.getBean("accountService");
//对象调用测试
accountService.run();
}
}
set方法注入:
标签:property 标签位置:bean的子标签 标签属性: name:用于注入时指定set的方法名称,去掉set,首字母并改成小写 value:用于给基本数据类型和String类型赋值 ref:用于指定对象类型参数赋值 优势:创建对象时没有明确限制,可以直接使用默认构造函数 弊端:有可能set方法没有执行
代码示例:
1.创建bin,给属性提供 get set方法
public class AccountService {
private String name;
private int age;
private Date birthdy;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthdy() {
return birthdy;
}
public void setBirthdy(Date birthdy) {
this.birthdy = birthdy;
}
public void run() {
System.out.println("对象创建成功name=" + name + ";age=" + age + ";birthdy=" + birthdy);
}
}
2.set方法注入配置示例
<?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="timeObject" class="java.util.Date"></bean>
<bean id="accountService" class="org.example.service.AccountService">
<property name="name" value="哈哈哈"></property>
<property name="age" value="11"></property>
<property name="birthdy" ref="timeObject"></property>
</bean>
</beans>
集合数据注入:
1.创建一个带有集合的bean
public class AccountService {
private String[] strs;
private List<String> list;
private Set<String> set;
private Map<String, String> map;
private Properties properties;
public String[] getStrs() {
return strs;
}
public void setStrs(String[] strs) {
this.strs = strs;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Set<String> getSet() {
return set;
}
public void setSet(Set<String> set) {
this.set = set;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void run() {
System.out.println(strs.toString()+"\n" + list.toString()+"\n"+set.toString() + "\n"+map.toString()+"\n"+properties.toString());
}
}
2.给集合赋值配置
结构相同的标签,标签可以互换
<?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="accountService" class="org.example.service.AccountService">
<!--数组赋值-->
<property name="strs">
<array>
<value>值1</value>
<value>值2</value>
</array>
</property>
<!-- List 赋值-->
<property name="list">
<list>
<value>值1</value>
<value>值2</value>
</list>
</property>
<!-- set赋值-->
<property name="set">
<set>
<value>值1</value>
<value>值2</value>
</set>
</property>
<!-- Map 赋值-->
<property name="map">
<map>
<entry key="map1" value="值1"></entry>
<entry key="map2" value="值2"></entry>
</map>
</property>
<!-- Properties 赋值-->
<property name="properties">
<props>
<prop key="p1">值1</prop>
<prop key="p2">值2</prop>
</props>
</property>
</bean>
</beans>