IOC容器小结
2021/7/17 6:06:58
本文主要是介绍IOC容器小结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
IOC 容器
一. IOC 底层原理
使用工厂模式+反射+xml的方式达到解耦合的目的,它们就是 IOC 的底层原理。 IOC 容器底层就是对象工厂。
Spring 提供两种 IOC 容器实现方法(两个接口):
- BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不推荐使用
- ApplicationContext:是 BeanFactory 子接口,提供更多更强大的功能
区别:BeanFactory 加载配置文件时不会创建对象,在获取对象时才创建(懒汉模式)。ApplicationContext 一加载配置文件就创建。由于Spring 通常用于 WEB,因此第二种在启动服务器时就先创建好对象可以使后续访问更流畅,所以一开始就加载更好。
BeanFactory 有两个实现类:
- FileSystemXmlApplicationContext,传入磁盘的全路径
- ClassPathXmlApplicationContext,传入 src 目录下的路径
二. Bean 管理
Bean 管理包括创建对象和注入属性
1. 基于 xml 文件
创建对象
默认通过无参构造方法创建
注入基本属性
-
方法一:使用 set 方法注入
类里必须有 set 方法
<bean id="book" class="com.abc.Book"> <property name="bname" value="hhh"/> </bena>
-
方法二:基于有参构造注入
类里必须有有参构造方法,不必有无参构造方法
<bean id="book" class="com.abc.Book"> <constructor-arg name="bname" value="hhh"/> <constructor-arg index="0" value="hhh"/> 通过索引注入 </bean>
特殊值注入:
-
注入 null
<property name="address"> <null/> </property>
-
包含特殊符号
-
使用转义字符,如
& < >
-
使用 CDATA
<property name="address"> <value><![CDATA[<<南京>>]]></value> </property>
-
注入外部 bean
<bean id="uesrService" class="com.service.UserService"> <property name="userDao" ref="userDaoImpl"/> </bean> <bean id="uesrDaoImpl" class="com.dao.UserDaoImpl"/>
注入内部 bean
<bean id="uesrService" class="com.service.UserService"> <property name="userDao"> <bean id="userDaoImpl" class="com.dao.UserDaoImpl"/> </property> </bean>
注入集合属性
<bean id="student" class="com.pojo.Student"> <!--数组类型--> <property name="courses"> <array> <value>java课程</value> <value>数据库课程</value> </array> </property> <!--List类型--> <property name="list"> <list> <value>张三</value> <value>小三</value> </list> </property> <!--map类型--> <property name="maps"> <map> <entry key="JAVA" value="java"/> <entry key="PHP" value="php"/> </map> </property> </bean>
集合中存放对象
<bean id="Student" class="com.pojo.Student"> <property name="courseList"> <list> <ref bean="course1"/> <ref bean="course2"/> </list> </property> </bean> <bean id="course1" class="com.pojo.Course"> <property name="cname" value="Spring5"/> </bean> <bean id="course2" class="com.pojo.Course"> <property name="cname" value="MyBatis"/> </bean>
提取出公共部分
先引入 util
命名空间
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd> <!--提取 list 集合类型属性--> <util:list id="bookList"> <value>易筋经</value> <value>九阳真经</value> </util:list> <bean id="book" class="com.pojo.Book"> <property name="list" ref="bookList"/> </bean> </beans>
自动装配
实际用的不多,都是用注解
byName 根据属性名称注入,注入的 bean 的 id 值要求和类属性名称一样
byType 根据属性类型注入,要求只能定义一个相同类型的 bean
<bean id="emp" class="com.pojo.Emp" autowire="byType"/>
引入外部属性文件
须引入context 命名空间
<context:property-placeholder location="a.property"/>
2. 基于注解
- @Component
- @Service
- @Controller
- @Repository
上面四个注解功能是一样的,都可以用来创建 bean 实例
步骤
- 引入依赖
spring-aop-5.2.6.RELEASE.jar
- 开启组件扫描
首先要引入 context 名称空间
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd <!--扫描多个包,逗号隔开--> <context:component-scan base-package="com.pojo,com.dao"/> <!--只扫描 Controller 注解--> <context:component-scan base-package="com.kuang.controller" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--除了 Controller 注解都扫描--> <context:component-scan base-package="com.pojo"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
- 在类上添加注解
package com.service; import org.springframework.stereotype.Service; // 如果不写 value 值,则默认 id 为类名,其中首字母小写 @Service("userService") public class UserService { }
属性注入
- @AutoWired:根据属性类型进行注入
- @Qualifier:根据属性名称进行注入
- @Resource:可以根据名称也可以根据类型注入
- @Value:注入基本类型属性
注解注入不依靠 set 方法
@Service("userService") public class UserService { @Autowired private UserDao userDao; public UserDao getUserDao() { return userDao; } }
package com.dao; import org.springframework.stereotype.Repository; @Repository public class UserDaoImpl implements UserDao{ @Override public void add() { System.out.println("hhh"); } }
@Qualifier 通常和 @Autowired 一起使用
- @Resource 根据类型注入
- @Resource(name="name") 根据名字注入
@Value("abc") private String name;
完全注解开发
package com.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; // 作为配置类替代 xml 文件 @Configuration @ComponentScan(basePackages = {"com.pojo"}) public class SpringConfig { }
public class MyTest { @Test public void dest() { ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService service = context.getBean("userService", UserService.class); } }
3. FactoryBean(工厂 bean)
Spring 有两种类型的 bean,一种普通 bean,一种工厂 bean。
普通 bean 中定义的类型就是返回类型,而工厂 bean 可以和返回类型不一样。
package com.pojo; import org.springframework.beans.factory.FactoryBean; public class MyBean implements FactoryBean<Course> { // 定义返回的bean @Override public Course getObject() throws Exception { Course course = new Course(); course.setCname("abc"); return course; } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } }
<!--会返回一个 Course 类型对象--> <bean id="myBean" class="com.pojo.MyBean"/>
4. bean 作用域
默认是单例(singleton)工厂,可以通过 scope 属性设置
scope=prototype 是多实例
5. bean 生命周期
- 创建 bean 实例
- 为 bean 的属性设置值和对其他 bean 的引用(set 方法)
- 调用 bean 的初始化方法
- 使用 bean
- 容器关闭时,调用 bean 销毁方法
package com.pojo; public class Order { private String oname; // 第一步 public void Order(){}; // 第二步 public void setOname(String oname) { this.oname = oname; } public void initMethod() { System.out.println("第三步"); } public void destoryMethod() { System.out.println("第五步"); } }
<!--第三、五步的初始化方法用 init-method、destory-method 参数配置--> <bean id="order" class="com.pojo.Order" init-method="initMethod" destory-method="destory-method"/>
如果引入后置处理器就会在第三步前后各插入一步,变成七步
这篇关于IOC容器小结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-22怎么通过控制台去看我的页面渲染的内容在哪个文件中呢-icode9专业技术文章分享
- 2024-12-22el-tabs 组件只被引用了一次,但有时会渲染两次是什么原因?-icode9专业技术文章分享
- 2024-12-22wordpress有哪些好的安全插件?-icode9专业技术文章分享
- 2024-12-22wordpress如何查看系统有哪些cron任务?-icode9专业技术文章分享
- 2024-12-21Svg Sprite Icon教程:轻松入门与应用指南
- 2024-12-20Excel数据导出实战:新手必学的简单教程
- 2024-12-20RBAC的权限实战:新手入门教程
- 2024-12-20Svg Sprite Icon实战:从入门到上手的全面指南
- 2024-12-20LCD1602显示模块详解
- 2024-12-20利用Gemini构建处理各种PDF文档的Document AI管道