参考IOC的理解与使用_ioc的作用_尼斯湖超大水怪的博客-CSDN博客
IOC(interversion of control)控制反转是一种编程的思想,将创建对象的权限由客户端(程序员)来new对象,改为由IOC容器统一新建管理所有对象。例如在Spring容器中,只用在applicationContext.xml中配置好,Spring容器会自动创建对象的bean
IOC的实现方式:
依赖查找(DL)
依赖注入(DI):目前Spring用的方式
依赖注入:
对象A被创建的时候,对象A在这个调控系统内所依赖的对象的引用 会传递给A
Spring容器实现Bean管理:
bean的管理包括:创建对象,注入属性(依赖注入)
Spring创建对象最底层接口:BeanFactory。
子接口:ApplicationContext
其实现类:FileSystemXmlApplicationContext("物理磁盘路径");
ClassPathXmlApplicationContext('配置文件的路径')
Spring的IOC容器中管理bean的生命周期:
1实例化:当启动Spring应用时,IOC容器就会为在配置文件中声明的每个<bean>创建一个实例。
2属性赋值:实例化后,Spring就通过反射机制给Bean的属性赋值。
3调用初始化方法:如果Bean配置了初始化方法,Spring就会调用它。初始化方法是在Bean创建并赋值之后调用,可以在这个方法里面写一些业务处理代码或者做一些初始化的工作。
4Bean运行期:此时,Bean已经准备好被程序使用了,它已经被初始化并赋值完成。
5应用程序关闭:当关闭IOC容器时,Spring会处理配置了销毁方法的Bean。调用销毁方法:如果Bean配置了销毁方法,Spring会在所有Bean都已经使用完毕,且IOC容器关闭之前调用它,可以在销毁方法里面做一些资源释放的工作,比如关闭连接、清理缓存等。
从两种方式xml配置方式和注解方式Spring讲述如何 (一、创建对象),(二、注入属性):
方式一:xml配置
一、创建对象
applicationContext.xml的配置:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean name="c" class="com.pojo.Student">
<property name="name" value="小明" />
</bean>
</beans>
Spring创建对象:<bean>标签
注意:class属性必须是实体类的全限定类名(包名+类名)
public class SpringTemp {
@Test
public void test1(){
//1.加载spring配置文件
BeanFactory context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2,获取配置创建的对象
Student student = context.getBean("person", Person.class);
student.setAge(18);
System.out.println(student.getAge());
}
}
xml文件中bean标签还有个属性scope
scope默认值是singleton,此时对象在上述步骤1实现beanfactory接口时(即加载配置xml文件时),对象就会被创建。此后getbean两遍,是同一个对象。
scope改为prototype:不是在加载 spring 配置文件时候创建 对象,在调用getBean 方法时候创建多实例对象。
二、注入属性
<!-- set方法注入属性 -->
<bean id="person" class="demo1.Person">
<!-- 使用property完成属性注入 name:类里面的属性名称 value:向属性中注入的值 -->
<property name="age" value="18"></property>
<property name="name" value="Tom"></property>
</bean>
特殊的属性注入:
1属性的value为null时
<property name="age" >
<null></null>
</property>
2属性为一个自定义的对象时
例如person对象里有一个属性时animal对象
<bean id="person" class="demo1.Person">
<property name="age" value="18"></property>
<property name="name" value="Tom"></property>
<property name="animal" ref="animal"></property>
</bean>
<bean id="animal" class="demo1.Animal"></bean>
<bean id="person" class="demo1.Person">
<property name="age" value="18"></property>
<property name="name" value="Tom"></property>
<property name="animal">
<bean id="animal" class="demo1.Animal"></bean>
</property>
</bean>
3属性为一个集合时
<bean id="demo" class="demo1.CollectionDemo">
<!-- 数组用array标签-->
<property name="animals">
<array>
<value>cat</value>
<value>dog</value>
</array>
</property>
<!-- Set集合用set标签-->
<property name="id">
<set>
<value>1001</value>
<value>1002</value>
</set>
</property>
<!-- List集合用list标签-->
<property name="name">
<list>
<value>大猫</value>
<value>旺财</value>
</list>
</property>
<!-- Map集合用map标签,但添加属性的时候用的是entry标签-->
<property name="owner">
<map>
<entry key="大猫" value="Tom"></entry>
<entry key="旺财" value="Jack"></entry>
</map>
</property>
</bean>
<bean id="person" class="demo2.Person">
<property name="name" value="二哈"></property>
<property name="animals">
<list>
<ref bean="animal1"></ref>
<ref bean="animal2"></ref>
<!-- 通过ref指向下面用xml创建的两个对象-->
</list>
</property>
</bean>
<bean id="animal1" class="demo2.Animals"></bean>
<bean id="animal2" class="demo2.Animals"></bean>
方式二:注解配置
需要引入包 spring-aop-5.2.6.RELEASE
配置文件/配置类
1、xml配置文件方法
<context:component-scan base-package="demo3" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller">
</context:include-filter>
</context:component-scan>
use-default-filters="false" 表示现在不使用默认 filter,自己配置 filter
context:include-filter 在这里面需要填两个参数type和expression,
tpye 里面填 annotation
expression里面是该注解所在的包再加上该注解名
2、设置配置类
@Configuration
@ComponentScan(basePackages = {"demo"})
public class SpringConfig {
}
注意!!!使用配置类注入对象,在建工厂加载时用AnnotationConfigApplicationContext加载配置类,就不再是用ClassPathXmlApplicationContext加载xml配置文件
@Test
public void test(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Person person = context.getBean("person", Person.class);
System.out.println(person);
}
一、创建对象
四种注解是加到类的上面表示创建对象,都可以被spring框架所扫描然后注入spring容器中,只不过一般是用在不用层上。
@Component
@Service
@Controller
@Respository
注解里面的value属性相当于xml中的bean标签的id属性,如果不写,则默认的属性值是类名的首字母小写;比如类名是PersonDmeo,则value的默认值则是personDemo
@Component(value = "person")
public class Person {
public void sout(){
System.out.println("ddddd");
}
}
二、注入属性
四个注解注入属性 Value、Autowired(根据属性类型注入)、Qualifier(根据名称注入)、Resource
前两个熟悉写,下面是常用的两个例子
@Component(value = "person")
public class Person {
@Autowired
private Animals animals;
@Override
public String toString() {
return "Person{" +
"animals=" + animals +
'}';
}
}
@Component(value = "person")
public class Person {
@Autowired
@Qualifier(value = "animal1")//里面需要有value的属性值需要与bean标签中的id一样
private Animals animals;
@Override
public String toString() {
return "Person{" +
"animals=" + animals +
'}';
}
}
@Component(value = "person")
public class Person {
@Value(value = "1001")
private int id;
@Value(value = "Tom")
private String name;
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}