控制反转(Ioc,Inversion of Control),是一个概念,一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,依赖的管理。
loc的实现:IoC是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式是依赖注入。应用广泛。
依赖: classA 类中含有classB的实例,在classA中调用classB的方法完成功能,即classA对classB有依赖。
依赖注入: DI(Dependency Injection),程序代码不做定位查询,这些工作由容器自行完成。
依赖注入DI是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
Spring的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象之间依赖关系的管理。
Spring框架使用依赖注入(DI) 实现IoC。
Spring容器是一个超级大工厂,负责创建、管理所有的Java对象,这些Java对象被称为Bean。Spring 容器管理着容器中Bean之间的依赖关系,Spring 使用“依赖注入”的方式来管理Bean之间的依赖关系。使用loC实现对象之间的解耦合。
1.1开发工具准备
利用maven工具,创建
实现步骤: 1.创建maven项目 2.加入maven的依赖 spring的依赖,版本5.3.7 junit依赖 3.创建类(接口和它的实现类),和没有使用框架一样,就是普通的类。 4.创建spring需要使用的配置文件 声明类的信息。这些类由spring创建和管理 5.测试spring创建的对象。
1.2Sprig的第一个程序
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--告诉spring创建对象 声明bean,告诉spring要创建某个类的对象 id是对象的自定义名称(唯一值)。spring通过这个名称找到对象 class:类的全限定名称(不能是接口,因为spring是反射机制) spring就完成SomeService someService = new SomeServiceImpl(); spring是把创建好的对象放到了map中,spring框架中有一个map存放对象的。 springMap.put(id的值,对象) 例如 springMap.put("someService",new someServiceImpl()); 一个bean标签只声明一个对象 --> <bean id="someService" class="cqutlc.service.Impl.someServiceImpl"></bean> <!--spring能创建一个非自定义的类--> <bean id="mydate" class="java.util.Date"/> </beans> <!--spring的配置文件 1.beans是根标签,spring中把Java对象成为bean 2.spring-beans.xsd是约束文件,和mybatis指定的类似 -->
package cqutlc; import cqutlc.service.Impl.someServiceImpl; import cqutlc.service.someService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test1 { @Test public void test1(){ someService someService=new someServiceImpl(); someService.doSome(); } /*spring默认创建对象的时间:在创建spring的容器时,他会创建配置文件中的所有对象*/ @Test public void test2(){ //使用spring容器创建的对象 //1.指定spring配置文件的名称 String config="beans.xml"; //2.创建表示spring容器的对象,ApplicationContext //ClassPathXmlApplicationContext;表示从类路径中加载spring的配置文件 ApplicationContext ac=new ClassPathXmlApplicationContext(config); //3.从容器中获取某个对象,你要调用对象的方法, //getBean("配置文件中的bena的id值"); someService service=(someService)ac.getBean("someService"); //使用spring创建好的对象 service.doSome(); } /*获取spring容器中的Java对象的信息*/ @Test public void test3(){ String config="beans.xml"; ApplicationContext ac=new ClassPathXmlApplicationContext(config); //使用spring提供的方法,获取容器中定义的对象的数量 int num=ac.getBeanDefinitionCount(); System.out.println(num); //容器中每个定义的对象的名称 String[] names= ac.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
1.3基于XML的DI
在spring配置文件中,给Java对象的属性赋值。
di:依赖注入,表示创建对象,给属性赋值。
di的实现语法:
1.在spring配置文件中,使用标签和属性完成,叫做基于xml的di实现
2.使用spring中的注解进行属性的赋值,叫做基于注解的di实现。
di的语法分类
1.set注入(设置注入): spring调用类的set方法,在set方法可以实现属性的赋值
2.构造注入,spring调用类的有参构造方法,创建对象。在构造方法中完成赋值。
set注入实例分析
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--声明student对象 注入:就是赋值的意思 简单类型:spring中规定Java的基本数据类型和string类型都是简单类型。 di:给属性赋值 1.set注入(设置注入):spring调用类的set方法,你可以在set方法中完成属性赋值 利用property --> <bean id="student" class="cqutlc.ba01.Student"> <property name="name" value="李四"/><!--调用setName...--> <property name="age" value="20"/>认准set方法 </bean> </beans>
当属性为引用类型时
2.引用类型的set注入:spring调用set方法 --> <bean id="student" class="cqutlc.ba02.Student"> <property name="name" value="李四"/><!--调用setName...--> <property name="age" value="24"/> <property name="school" ref="school"/> </bean> <bean id="school" class="cqutlc.ba02.School"> <property name="name" value="cqut"/> <property name="address" value="cq"/> </bean>
构造注入
得有构造参数
2.构造注入 spring调用类的有参数构造方法,在创建对象的同时给属性赋值 构造注入使用 --> <bean id="student" class="cqutlc.ba03.Student"> <constructor-arg name="name" value="lc"/> <constructor-arg name="age" value="19"/> <constructor-arg name="school" ref="myschool"/> </bean> <bean id="myschool" class="cqutlc.ba03.School"> <property name="name" value="cqut"/> <property name="address" value="cq"/> </bean>
引用类型的自动注入
byName和byType
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 引用类型的自动注入:spring框架根据某些规则可以给引用类型赋值。不用你再给引用类型赋值了 使用的规则常用的是 1.byName(按名称注入):Java类中引用类型的属性名和spring容器中(配置文件)<bean>的id名称一样。 且数据类型一致,这样的容器中的bean,spring能够赋值给引用类型。 2.byType(按类型注入):Java类中引用类型的数据类型和spring容器中(配置文件)<bean>的class是同源关系。 <bean id="" class="" outowire="byType"> --> <bean id="student" class="cqutlc.ba04.Student" autowire="byName"> <property name="name" value="李四"/><!--调用setName...--> <property name="age" value="24"/> <!--<property name="school" ref="school"/>--> </bean> <bean id="school" class="cqutlc.ba04.School"> <property name="name" value="cqut"/> <property name="address" value="cq"/> </bean> </beans>
多个配置文件的优势
1.每个文件的大小比一个文件要小得多。效率高
2.避免多人竞争带来的冲突
多文件的分配方式:
1.按功能模块,一个模块一个配置文件。
2.按类的功能,数据库相关,做事务处理的,做service的。
包含关系的配置路径
1.4基于注解的DI
通过注解完成Java对象的创建,属性赋值
使用注解的步骤
- 加入maven的依赖spring-context,在你加入spring-context的同时,间接加入spring-aop的依赖。使用注解必须使用spring-aop依赖
- 在类中加入spring的注解(多个不同功能的注解)
- 在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置。
学习的注解有:
1.@Component 2.@Repository 3.@Service 4.@Controller 5.@Value 6.@Autowired 7.@Resource
简单类型
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--声明组件扫描器(component-scan), 组件就是Java对象,所以就是找Java对象 base-package:指定注解在你的项目中的包名 component-scan工作方式:spring会扫描遍历base-package指定的包 把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象和给属性赋值。 --> <context:component-scan base-package="cqutlc.ba01"/> </beans>
package cqutlc.ba01; import org.springframework.stereotype.Component; /* * @Component:创建对象的,等同于<bean>的功能 * 属性value: 就是对象的名称,也就是bean的id值,value值是唯一的,创建的对象在整个spring容器中就一个 * 位置:在类的上面写注解 * */ //等同于<bean id="myStudent" class="cqutlc.ba01.Student"/> //@Component(value = "myStudent") //省略value //@Component("myStudent") //不指定对象名称,由spring提供默认名称(首字母小写类名) @Component public class Student { private String name; private Integer age; public void setName (String name) { this.name = name; } public void setAge (Integer age) { this.age = age; } @Override public String toString () { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package cqutlc; import cqutlc.ba01.Student; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class test1 { @Test public void test(){ String config="applicationContext.xml"; ApplicationContext ac=new ClassPathXmlApplicationContext (config); //从容器中获取对象 Student student=(Student) ac.getBean ("student"); System.out.println (student); } }
* spring中和@Component功能一致,创建对象的注解还有: * @Repository(用在持久层上):放在dao的实现类上面, * 表示创建dao对象,dao对象是能访问数据库的。(持久层注解) * * @Service(用在业务层类的上面):放在service的实现类上面, * 创建service对象,service对象是做业务处理的,可以有事物等功能的。 * * @Controller(用在控制器的上面):放在控制器(处理器)类的上面,创建控制器对象的, * 控制器对象可以接收用户提交的参数和显示请求的处理结果。 * * 以上三个注解的使用语法和@Component是一样的,都能够创建对象,但是这三个注解还有额外的功能----给项目分层
指定多个包的三种方式
- 使用多次组件扫描器标签,指定不同的包
- 使用分隔符(分号或者逗号)分隔多个包名
- 指定父包
引用类型
@Autowired:spring框架提供的注解,实现引用类型的赋值spring中通过注解给引用类型赋值,使用的是自动注入,支持byName和byType@Autowired默认使用@byType自动注入
位置:
1.在属性定义的上面,无需set方法,推荐使用。被引用的类必须提前利用@Component注解标识。
2.在set方法的上面
属性:required,是一个boolean类型的,默认是true,表示引用类型失败时,程序报错并终止运行。要是false则正常运行,赋值为null,最好用true,可以及时发现错误!
如果要使用byName的方式
1.在属性的上面加上@Autowired
2.在属性上面加入@Qualifier(vlaue=“bean的id”):表示使用指定名字的bean完成赋值。
@Resource:来自于JDK中的注解,spring框架提供了对这个注解功能的支持。可以用它给引用类型赋值,使用的也是自动注入原理,支持byName,byType。默认是byName
位置:
1.在属性定义的上面,无需set方法,推荐使用
2.在set方法的上面先使用byName自动注入,假如失败了就会再使用byType
如何只使用byName?
需要新增加一个属性name name的值为bean的id名称
标签:容器,配置文件,创建,对象,spring,Spring,注解,IOC,反转 From: https://blog.csdn.net/m0_52064839/article/details/144648096