Spring中的IOC容器
一、IOC底层原理与概念
-
什么是IOC
- 控制反转,将 对象创建 和 对象之间的调用过程 教给Spring
- 目的:为了降低耦合度
-
IOC底层原理
- xml解析
- 工厂模式
- 反射
原方式:
演变->工厂设计模式:
IOC现有过程:
利用xml解析:获取文件路径
反射:通过Class.forName(路径)获取创建对象
二、IOC接口(BeanFactory)
-
IOC思想基于IOC容器完成,IOC底层就是对象工厂
-
Spring提供IOC的实现接口
- ApplicationContext
- BeanFactory接口的子接口
- 提供更加多的功能,供开发人员使用
- 特点:加载配置文件xml的时候直接创建对象
- BeanFactory
- IOC容器最基本的实现方式(Spring内部进行使用,不提倡开发人员使用)
- *特点:加载配置文件xml的时候不会创建对象,获取对象的时候才创建配置文件
- ApplicationContext
-
ApplicationContext的扩展接口实现类
- ClassPathXmlApplicationContext:对应src下的工程路径
- FileSystemXmlApplicationContext:电脑盘中的绝对路径
- ConfigurableApplicationContext:扩展实现功能
三、IOC操作Bean管理 基于xml(底层原理机制,直接使用请跳过直接看 四)
-
Bean管理操作
- Spring创建对象
- Spring注入属性
-
基于xml方式 创建对象
- 在Spring配置文件中使用bean标签,标签添加对应内容,既可实现创建
-
bean标签属性
- *id:对象的唯一标识
- *class:类的全路径
-
创建对象的时候,默认执行无参构造方法
-
基于xml方式 注入属性*
-
DI:依赖注入,就是注入属性
-
第一种方式:利用setter方法进行注入
- 创建setter方法
public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; }
- Spring配置文件中
<!--配置User对象--> <bean id="user" class="test.User"> <!--使用property标签完成属性的注入 使用键值对的方法 --> <property name="age" value="10"></property> <property name="name" value="lmz"></property> </bean>
-
第二种方式:利用有参构造注入
<!--通过有参构造方法配置--> <bean id="order" class="test.Order"> <constructor-arg name="address" value="China"></constructor-arg> <constructor-arg name="id" value="1"></constructor-arg> </bean>
-
设置空值()
<constructor-arg name="address" > <null/> </constructor-arg>
-
注入外部bean属性*
-
例如:在Service层调用Dao层的实现类(方法同上)
-
1.创建属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MKoN2dwG-1658987323531)(https://s2.loli.net/2022/07/28/PXbnizYeEC2sGqS.png)]
-
2.使用 ref 配置xml文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YncwlIid-1658987323532)(https://s2.loli.net/2022/07/28/aBJsqhUMRSPgorY.png)]
-
-
注入内部bean
-
内部bean:例如bean中有一对多关系:一个部门多个员工
-
1.在bean中写好属性
-
2.利用setter方法添加属性
-
-
-
注入集合属性
-
例如:有一个times类型的属性为int数组类型
<!--数组类型的注入--> <property name="times"> <array> <value>1</value> <value>10</value> <value>11</value> <!--map类型的注入标签为entry--> </array> </property>
-
例如:有一个times类型的属性为对象(Course)数组类型
-
将集合抽取,变为共有属性,需要时调用
-
<!--抽取list集合类型注入--> <util:list id="Psd"> <value>dasda</value> <value>wqeqweqw</value> </util:list> <!--使用ref进行注入--> <property name="logPsd" ref="Psd"></property>
-
-
-
工厂Bean的使用
- 普通bean只能返回指定的类型
<!--定义类型为User--> <bean id="user" class="test.User">
//得到返回类型也是User User user = context.getBean("user", User.class);
- 在xml里定义的bean类型可以和返回类型不一样
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LmqeitKR-1658987323533)(https://s2.loli.net/2022/07/28/4o1tbJlHq9sQijK.png)]
其余步骤和xml配置一致
-
-
Bean的作用域
-
在Spring中可以设置bean的实例是单实例还是多实例对象
-
单实例:两次根据xml创建地址相同**(默认singleton)**
-
多实例:两次根据xml创建地址不同**(prototype)**
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XIr3LHHF-1658987323534)(https://s2.loli.net/2022/07/28/puDrEomN8dwKYCz.png)]
-
放入到request或session中**(request/session)**
-
-
-
Bean的 生命周期
-
通过构造器创建bean实例(无参构造器中)
-
设置bean的属性和其他bean的引用(set方法中)
-
调用bean的初始化方法(需要进行配置)
-
bean可以正常调用
-
容器关闭的时候,调用销毁方法(需要进行配置)
//1.加载配置文件 ApplicationContext context =new ClassPathXmlApplicationContext("Bean1.xml"); context.close();
-
-
xml 的自动装配
-
定义:根据属性 名称 或 类型,Spring自动将匹配的属性注入
-
根据名称**(byName),bean的id值和属性名称一样**
-
根据类型**(byType)**
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-weHNXaBB-1658987323536)(…/…/myimage/image-20220720095951759.png)]
-
-
-
外部属性文件
-
对比:直接配置数据库信息
<!--直接配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/project"></property> <property name="username" value="root"></property> <property name="password" value="password"></property> </bean>
-
从外部属性文件配置数据库连接池
-
将Properties文件引入Spring配置
- 引入context名称空间
-
引入外部文件
-
-
四、IOC操作Bean管理 基于注解
-
注解示例
@myAnnotation(name="川泽")
- 使用注解 可以简化xml配置
-
Spring针对Bean管理中创建对象的注解
-
@Component**(普通注解)**
-
@Service**(建议在Service层)**
-
@Controller**(建议在Web层)**
-
@Repository**(建议在Dao层)**
上面四个注解功能一样,都可以创建bean实例
-
-
注解 创建Bean对象
-
引入Aop包
-
开启组件扫描
- 方式一
-
方式二
<!--方式二,指定父级目录下的 特殊注解进行扫描--> <!-- use-default-filters="false":不使用默认扫描方式 type:扫描注解 expression:扫描有Service标识的注解 --> <context:component-scan base-package="test_annotation" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan>
-
创建类后在类上添加注解
/** * 注解里面value值可以省略 * 默认为类名,第一个字母小写 */ @Service(value = "userService") //相当于<bean id="userService" class="..."> public class UserService { public void add_(){ System.out.println("add"); } }
-
-
Spring针对Bean管理中 注入属性的注解
-
@Autowired:根据属性类型进行自动装配
-
@Qualifier:根据属性名称进行注入
-
(需要和@Autowired一起使用)
@Autowired//自动装配属性 @Qualifier(value = "userDaoImp")//名称限制 private UserDao userDao;
-
-
@Resource:可以根据类型注入,可以根据名称注入(不推荐)
@Resource//自动装配属性 @Resource(value = "userDaoImp")//名称限制 private UserDao userDao;
-
@Value:注入普通类型
@Value(value = "1") Integer a;
-
-
注解 注入属性
-
创建属性
-
在Service层注入到对象,在属性上面使用注解
-
-
纯注解开发(SpringBoot应用)
-
创建测试类,代替xml
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qnCARVTA-1658987323540)(https://s2.loli.net/2022/07/28/ALyuVvrj1XRBWHk.png)]
-
添加配置注解
-
调用时函数与 xml有所不同
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0bYtBJG-1658987323541)(https://s2.loli.net/2022/07/28/eOSxLB2obQZuGYU.png)]
-