Ioc:控制反转,把对象的创建和对象之间的调用过程交给spring进行管理;
使用 Ioc 的目的:解耦(降低耦合度);
xml解析、工厂模式、反射;
1、ioc思想基于ioc容器完成、ioc容器底层就是对象工厂;
2、spring提供了ioc容器的两种方式:(两个接口);
(1)、BeanFactory:ioc容器的基本实现,是spring内部的使用接口,不推荐开发人员进行使用;
在加载配置文件的时候不会创建对象、在获取(使用)对象的时候才会进行创建;
(2)、ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用;
在加载配置文件的时候会直接创建对象;
(3)、Application接口的实现类;
1、spring创建对象;
2、spring注入属性;
1、基于xml配置文件;
2、基于注解;
1、基于xml方式创建对象:
(1)、在spring配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象的创建;
(2)、bean标签中有很多属性、介绍常用属性:
id属性:唯一标识;
class属性:类的全路径;
(3)、创建对象时默认也是调用无参构造器完成对象的创建;
2、基于xml方式注入属性:
(1)、DI:依赖注入、就是注入属性;
方式一:使用 setter 方法进行注入;
方式二:使用有参构造器进行注入;
@Test void testBean() { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); User user = context.getBean("user",User.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" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"> <!--setter注入:实体类中需要有当前 setter方法--> <bean id="user" class="com.ithailin.interview.up.pojo.User"> <property name="id" value="1"/> <property name="name" value="张三"/> </bean> <!--构造器注入:实体类中需要有当前 有参构造器--> <bean id="user2" class="com.ithailin.interview.up.pojo.User"> <constructor-arg name="id" value="2"/> <constructor-arg name="name" value="李四"/> </bean> <!--构造器注入:实体类中需要有当前 有参构造器,可以使用index(索引值)来表示 name属性--> <bean id="user3" class="com.ithailin.interview.up.pojo.User"> <constructor-arg index="0" value="3"/> <constructor-arg index="1" value="王五"/> </bean> <!--setter注入:实体类中需要有当前 setter方法 属性设置null值--> <bean id="user4" class="com.ithailin.interview.up.pojo.User"> <property name="id" value="4"/> <property name="name"> <null/> </property> </bean> <!--setter注入:实体类中需要有当前 setter方法 属性设置带有特殊符号的值 若特殊符号是 ”< >“,则可以将其进行转义成 <(小于) >(大于) --> <bean id="user5" class="com.ithailin.interview.up.pojo.User"> <property name="id" value="<>>"/> <property name="name"> <value><![CDATA[带有特殊符号的值]]></value> </property> </bean> <!--注入外部bean 使用setter的方式注入,属性是一个对象时使用 ref来设置,而不是使用 value; ref属性:是创建 bean的id值; 使用setter注入的方式可以解决spring循环依赖的问题(A对象中有属性 对象B、B对象中有属性 对象A) 构造器的注入方式无法解决spring循环依赖的问题; --> <bean id="a" class="com.ithailin.interview.three.spring.circulardepend.A" scope="prototype"> <property name="b" ref="b"></property> </bean> <bean id="b" class="com.ithailin.interview.three.spring.circulardepend.B"> <property name="a" ref="a"></property> </bean> <!--注入内部 bean 使用setter的方式注入 --> <bean id="a2" class="com.ithailin.interview.three.spring.circulardepend.A"> <property name="b"> <bean id="b2" class="com.ithailin.interview.three.spring.circulardepend.B"> </bean> </property> </bean> <!--使用setter注入一个 Stu 对象 属性为 String[]、List、Map、Set、List<User> --> <bean id="stu" class="com.ithailin.interview.up.spring5.Stu"> <!--数组类型属性注入--> <property name="arrs"> <array> <value>array1</value> <value>array2</value> </array> </property> <!--List类型属性注入--> <property name="lists"> <list> <value>list1</value> <value>list2</value> </list> </property> <!--Map类型属性注入--> <property name="maps"> <map> <entry key="java" value="JAVA"></entry> <entry key="vue" value="VUE"></entry> </map> </property> <!--set类型属性注入--> <property name="sets"> <set> <value>mysql</value> <value>redis</value> </set> </property> <!--list类型属性注入,其中值为 User 类型--> <property name="userList"> <list> <ref bean="user"></ref> <ref bean="user2"></ref> </list> </property> </bean> <!--setter注入一个 List对象--> <util:list id="bookList"> <value>本</value> <value>书</value> <value>笔</value> </util:list> </beans>
1、spring中有两种 bean,一种是普通 bean,另一种就是 FactoryBean;
普通bean:在配置文件中定义的类型就是返回的类型;
工厂bean:在配置文件中定义的类型可以和返回的类型不一样;
import org.springframework.beans.factory.FactoryBean; public class MyFactoryBean implements FactoryBean { //定义返回的Bean @Override public Object getObject() throws Exception { return new Stu(); } //定义返回的Bean的类型 @Override public Class<?> getObjectType() { return null; } //当前的Bean是否为单例 @Override public boolean isSingleton() { return false; } }
<!--定义的bean、返回是一个 FactoryBean--> <bean id="beanFactory" class="com.ithailin.interview.up.spring5.MyFactoryBean"> </bean>
在spring中,可以在<bean>的scope属性设置bean的作用域,以决定这个bean是单实例的还是多实例的;
默认情况下,spring只为每个ioc容器声明的bean创建唯一一个实例,整个ioc容器范围内都能共享这个实例,所有后续的getBean()和bean的引用都将返回这个唯一的bean实例,该作用域被称为singleton,他是所有bean的默认作用域;
1、通过构造器创建 bean 的实例(无参构造器);
2、为 bean 的属性设置值,和对其它 bean 的引用(调用 setter 方法);
3、调用 bean 的初始化方法(需要进行配置初始化方法);
4、bean 可以进行使用了(对象获取到了);
5、当容器关闭的时候,调用 bean 的销毁方法(需要进行配置销毁的方法);
原文:https://www.cnblogs.com/jhdhl/p/14832258.html