Spring中IOC的理解
Spring中IOC的理解
1、什么是IOC?
(1)控制反转。把对象创建和对象间的调用过程交给Spring进行管理。
(2)使用IOC的目的:为了耦合度降低。
2、IOC底层原理?
(1)xml解析、工厂模式、反射
(2)图解
原始调用方式(耦合度太高,dao如果变了service也要跟着变):
引入工厂模式解除上面两个类的耦合度(但是工厂和service出现了新的耦合):
IOC解耦过程(进一步降低耦合度)
第一步:xml配置文件,配置创建的对象,示例:<bean id="aaa" class="xxx.dao"></bean>
第二步:有service和dao类,创建工厂类,示例:
IOC接口
- IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
- Spring提供IOC容器实现两种方式:(两个接口)
- BeanFactory:最基本接口,供内部人员使用。加载配置文件时不会去创建对象,在获取对象或者使用对象时才去创建对象。(.getBean方法时)
- ApplicationContext:BeanFactory接口的一个子接口。提供了更多功能,一般由开发人员使用。加载配置文件时就会把在配置文件中对象进行创建。
3.ApplicationContext的主要实现类(File那个类是盘里全路径,Class那个是类路径位置):
IOC操作:Bean管理
1、什么是Bean管理(2个操作)
(1)Spring创建对象
(2)Spring注入属性
2、Bean管理操作有两种方式
(1)基于xml配置文件方式实现
(2)基于注解方式实现
IOC操作Bean管理(基于xml方式)
1、基于xml创建对象
<bean id="aaa" class="xxx.dao"></bean>
bean中常用属性:
id:唯一标识
class:类全路径
创建对象时,默认执行无参构造,完成对象创建。
2、基于xml注入属性
(1)DI:依赖注入,注入属性,是IOC一种实现
第一种注入方式:使用set方法进行注入
创建一个类,创建其对应set方法;
在Spring配置文件中配置对象创建,配置属性注入,示例如下:
- <bean id="book" class="org.zhaojianhui.Spring.Book">
<property name="name" value="我的世界"/>
<property name="price" value="15.0"/>
</bean>
第二种注入方式:使用有参构造进行注入
创建一个类,定义属性以及有参构造
- //有参构造注入
public Book(String name, String price) {
this.name = name;
this.price = price;
}
Spring配置文件中编写:
- <bean id="book" class="org.zhaojianhui.Spring.Book">
<constructor-arg name="name" value="我的爱人"></constructor-arg>
<constructor-arg name="price" value="16.0"></constructor-arg>
</bean>
P名称空间注入(底层还是set注入):
1、加一个p命名空间
2、进行属性注入:
- xml中其他属性注入:
1、空值注入
- 2、属性值包含特殊符号:
转义<>:< >
注入属性:外部Bean
- 创建service类和dao类,省略此处。
2.在service中调用dao
- //创建userDao类型,申明set方法
- private UserDao userDao;
- public void setUserDao(UserDao userDao) {
- this.userDao = userDao;
- }
- public void add() {
- System.out.println("service add!!!");
- userDao.update();
- }
3.在Spring配置文件中进行配置
- <!--service和dao对象创建-->
- <bean id="userService" class="org.zhaojianhui.Spring.service.UserService">
- <!--注入userdao对象,name是类里的属性名称,
- ref是创建UserDao中bean标签的id,注入外部bean-->
- <property name="userDao" ref="userDao"></property>
- </bean>
- <bean id="userDao" class="org.zhaojianhui.Spring.dao.UserDaoImpl"></bean>
注入属性:内部Bean
- 一对多关系:例如部门对员工示例
- //部门类
- public class Dept {
- private String dname;
- public void setDname(String dname) {
- this.dname = dname;
- }
- }
- //员工类
- public class Emp {
- private String name;
- private String gender;
- private Dept dept;
- public void setDept(Dept dept) {
- this.dept = dept;
- }
- public void setName(String name) {
- this.name = name;
- }
- public void setGender(String gender) {
- this.gender = gender;
- }
- }
2.在Spring配置文件中进行配置
- <!--内部bean-->
- <bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp">
- <property name="name" value="zs"></property>
- <property name="gender" value="男"></property>
- <!--对象类型属性-->
- <property name="dept">
- <bean id="demp" class="org.zhaojianhui.Spring.Bean.Dept">
- <property name="dname" value="安保部"></property>
- </bean>
- </property>
- </bean>
级联赋值:
写法1:
- <bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp">
- <property name="name" value="zs"></property>
- <property name="gender" value="男"></property>
- <!--对象类型属性-->
- <property name="dept" ref="depts"></property>
- </bean>
- <bean id="depts" class="org.zhaojianhui.Spring.Bean.Dept">
- <property name="dname" value="安保部"></property>
- </bean>
写法2:
- <property name="dept.dname" value="体育部"></property>,对应Emp实体需要生成dept属性的getter方法才能完成!
- IOC操作Bean管理(xml注入集合属性)
1、注入数组类型属性
2、注入List类型属性
3、注入Map类型属性
配置文件中代码示例如下:
- <!--数组、List、Map注入-->
- <bean id="stu" class="org.zhaojianhui.Spring.Bean.Stu">
- <property name="course">
- <array>
- <value>语文</value>
- <value>数学</value>
- </array>
- </property>
- <property name="list">
- <list>
- <value>张三</value>
- <value>三儿</value>
- </list>
- </property>
- <property name="map">
- <map>
- <entry key="JAVA" value="java">
- </entry>
- <entry key="PHP" value="php"></entry>
- </map>
- </property>
- </bean>
- 在集合里设置对象类型值:
- <!--注入list集合类型,值是对象-->
- <property name="courseList">
- <list>
- <ref bean="course1"></ref>
- <ref bean="course2"></ref>
- </list>
- </property>
- </bean>
- <bean id="course1" class="org.zhaojianhui.Spring.Bean.Course">
- <property name="cname" value="Spring"></property>
- </bean>
- <bean id="course2" class="org.zhaojianhui.Spring.Bean.Course">
- <property name="cname" value="MVC"></property>
- </bean>
把集合注入部分提取出来
1、在配置文件中引入一个名称空间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">
- </beans>
2、使用util标签完成list集合提取注入
- <!--提取list集合属性注入-->
- <util:list id="list">
- <value>w</value>
- <value>q</value>
- <value>r</value>
- </util:list>
- <!--注入使用-->
- <bean id="stu" class="org.zhaojianhui.Spring.Bean.Stu">
- <property name="list" ref="list">
- </property>
- </bean>
- IOC操作Bean管理(FactoryBean)
1、Spring有两种Bean,一种普通Bean,另外一种工厂Bean
2、普通Bean:在配置文件中定义Bean类型就是返回类型
3、工厂Bean:在配置文件中定义Bean类型可以和返回类型不一样
Bean的作用域:
默认单例,可以在配置文件中修改作用域,在bean标签的scope属性用于设置,属性值有singleton,prototype(多例),request,session
区别:
设置为单例时,加载配置文件时就会创建单例对象,设置为多例时候不是在加载配置文件时创建对象,而是在调用getBean方法时候创建多实例对象。
Bean的生命周期:
1、通过构造器创建bean示例(无参构造)
2、为bean的属性设置值和对其他bean的引用(调用set方法)
把bean实例传递给bean后置处理器方法(如果使用了后置处理器就会多两个步骤,即实现BeanPostProcessor方法)
3、调用bean的初始化方法
把bean实例传递给bean后置处理器方法
4、bean可以使用了(对象获取到了)
5、当容器关闭时,调用Bean的销毁方法
XML自动装配
1、基于名称 2、基于类型
- <!--自动装配,bean标签属性autowire配置自动装配,byName根据属性名称注入(bean的id值和类属性名称一样),byType根据属性类型注入
- (但是相同类型的bean不能定义多个)-->
- <bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp" autowire="byName"></bean>
- <bean id="dept" class="org.zhaojianhui.Spring.Bean.Dept">
- <property name="dname" value="开发部门"></property>
- </bean>
引入外部属性文件(以数据库信息为例):
1、直接配置数据库信息
2、通过引入外部属性文件配置数据库连接池
1、引入context命名空间
2、spring配置文件中引入外部文件
- <!--引入外部属性文件-->
- <context:property-placeholder location="classpath:jdbc.properties"/>
3、使用${属性}填充内容
- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
- <property name="driverClassName" value="${prop.driverClass}"></property>
- <property name="url" value="${prop.url}"></property>
- <property name="username" value="${prop.userName}"></property>
- <property name="password" value="${prop.password}"></property>
- </bean>
IOC操作Bean管理(基于注解方式)
1、什么是注解?
1、@注解名称,注解可以作用在类、方法、属性上
2、使用目的:简化xml配置
2、Spring针对Bean管理中创建对象提供注解:
1、@Component:
2、@Service:
3、@Controller:
4、@Repository:用于dao层一般
3、基于注解方式演示对象创建(注解的value值默认为类首字母小写)
第一步:引入aop依赖
第二步:开启组建扫描
- <!--开启组件扫描-->
- <context:component-scan base-package="org.zhaojianhui.Spring"></context:component-scan>
开启组件扫描细节(设置哪些扫描哪些不扫描):
- <!--use-default-filters="false",表示现在不使用默认filter,自己配置filter,下面配置表示只扫描包下带有Controller注解的类-->
- <context:component-scan base-package="org.zhaojianhui.Spring" use-default-filters="false">
- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- </context:component-scan>
基于注解方式实现属性注入:
(1) @Autowired:根据属性类型进行自动装配
1、在service中注入dao对象(此时加了注解后不需要set方法)
- @Service
- public class UserService {
- @Autowired
- private UserDao userDao;
- public void add() {
- System.out.println("service add!!!");
- userDao.update();
- }
- }
(2)@Qualifier(需要和Autoqired一起使用):根据属性名称注入
- @Autowired
- @Qualifier(value = "userDaoImp1")
- private UserDao userDao;
(3)@Resource:可以根据名称/类型注入
- @Resource//根据类型注入
- @Resource(name = "userDaoImp1")//根据名称注入
- private UserDao userDao;
(4)@Value:注入普通类型
- @Value(value = "abc")
- private String name;
纯注解开发:
(1)创建配置类,替代xml文件
- @Configuration//作为配置类,替代xml文件
- @ComponentScan(basePackages = {"org.zhaojianhui.Spring"})//需要扫描的包
- public class SpringConfig {
- }
(2)编写测试类
- public void test() {
- // ApplicationContext appo = new ClassPathXmlApplicationContext("bean2.xml");
- ApplicationContext appo = new AnnotationConfigApplicationContext(SpringConfig.class);;//加载配置类
- UserService userService = appo.getBean("userService", UserService.class);
- System.out.println(userService);
- userService.add();
- }
Spring中IOC的理解的更多相关文章
- 浅析对spring中IOC的理解
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
- 对Spring中IOC和DI的理解
前几篇讲了Spring中IOC和DI的用法,本篇应该放到三篇之前,但一直没有想到好的讲解方式,后参考https://blog.csdn.net/luoyepiaoxue2014/article/det ...
- Spring中IOC和AOP的详细解释(转)
原文链接:Spring中IOC和AOP的详细解释 我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入,和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂 ...
- Spring中IoC的入门实例
Spring中IoC的入门实例 Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用.这一章先从Spring的IoC开始.所谓IoC就是一个用XML来定义生成对象的模式,我们看看如 ...
- 对spring中IOC和AOP的理解
IOC:控制反转也叫依赖注入.利用了工厂模式. 为了方便理解,分解成每条以便记忆. 1.将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器 ...
- Spring对IOC的理解
一.IOC控制反转和DI依赖注入 1.控制反转,字面可以理解为:主动权的转移,原来一个应用程序内的对象是类通过new去主动创建并实例化的,对对像创建的主动权在程序代码中.程序不仅要管理业务逻辑也要管理 ...
- Spring 中 IoC 容器简介
IoC 是一种通过描述来生成或者获取对象的技术,可以说 Spring 是一种基于 IoC 容器编程的框架 在一个系统中可以生成各种对象,并且这些对象都需要进行管理.为了描述这些对象关系,我们需要一个容 ...
- spring中IOC和AOP原理
IoC(Inversion of Control): (1)IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控.控制权由应用代码中转 ...
- Spring中ioc的实现原理
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
随机推荐
- Google 开发console查找元素或方法
F12 后 在console中输入: $("#R")[0] 查找ID 为R的元素, 如需打印出元素属性值,则输入: console.dir($("#R")[0] ...
- java js转码
public static String escape(String src) { int i; char j; StringBuffer tmp = new StringBuffer(); tmp. ...
- 高德地图——添加标记的两种方法&删除地标记的两种方法
添加标记: 1.marker.setMap(map); 2.marker.add([marker]); 删除标记: 1.marker.setMap(null); 2 map.remove([marke ...
- Win10 pip install augimg 报 OSError: [WinError 126] 找不到指定的模块,解决办法
第一种Win10下python成功安装augimg的方法: 下载Shapely,地址https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely,选择对应版本 ...
- Servlet学习笔记(一)之Servlet原理、初始化、生命周期、结构体系
Servlet是用java语言编写的应用到Web服务器端的扩展技术,与java对象的区别是,Servlet对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持(以下会介绍原因, ...
- Sentry For React 完整接入详解(2021 Sentry v21.8.x)前方高能预警!三万字,慎入!
内容源于:https://docs.sentry.io/platforms/javascript/guides/react/ 系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - ...
- Docker编排工具Docker Compose的使用
一.安装docker compose 官网推荐方式之一: sudo curl -L "https://github.com/docker/compose/releases/download/ ...
- NOIP模拟测试17&18
NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...
- NOIP模拟「random·string·queen」
T1:random 我又来白剽博客了: 详细证明请看土哥 土哥写的不是很详细,我在这里详细写一下: 首先,对于f[n]的式子: 加一是那一个对的贡献,大C是选其余的几个数,\(2^ ...
- 了解mysql concat()函数
concat(arg1,arg2,....):将形参对应字段的值组合成一个字符串 假设:现在有一张学生表(test_user) 将这三个字段组合成一个字符串作为第四个字段 select test_us ...