Spring-IOC

Spring概述

Spring全家桶:spring、springmvc、spring boot、spring cloud

spring:出现是在2002左右,解决企业开发的难度。减轻对项目模块之间的管理。

​ 类和类之间的管理,帮助开发人员创建对象,管理对象之间的关系。

​ spring核心技术:ioc、aop。能实现模块之间,类之间的解耦合。

依赖:classa中使用了classb的属性或者方法,叫做classa依赖classb

spring官网:spring.io

spring优点

轻量

Spring框架使用的jar都比较小,一般在1M以下或者几百kb。Spring核心功能的所需的jar总共在3M左右。

Spring框架运行占用的资源少,运行效率高。不依赖其他jar

针对接口编程,解耦合

Spring提供了loc控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。

AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付

在Spring中,开发人员可以从繁杂的事务管理代码中解脱出来,通过声明方式灵活地进行事务的管理,提高开发效率和质量。

方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts、Hibernate、MyBatis)等的直接支持。简化框架的使用。Spring像插线板一样,其他框架是插头,可以容易的组合到一起。需要使用哪个框架,就把这个插头放入插线板,不需要可以轻易的移除。

Spring体系结构

Spring-IOC_第1张图片

框架怎么学:框架是一个软件,是其他人写好的软件。

1)知道框架能做什么,mybatis–访问数据库,对表中的数据执行增删改查。

2)框架的语法,框架要完成一个功能,需要一定的步骤支持的。

3)框架的内部实现,框架的内部怎么做,原理是什么。

4)通过学习,实现一个属于自己的框架。

Spring的核心功能 ioc

ioc(Inversion of Control):控制反转,是一个理论,概念,思想。

描述的是:把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是由其他的外部资源完成。

控制:创建对象,对象的属性赋值,对象之间的关系管理。

反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现,由容器代替开发人员管理对象,创建 对象,给属性赋值。

正转:由开发人员在代码中,使用new构造方法创建对象,开发人员主动管理对象。

public static void  main(String args[]){
	Student student=new Student(); //在代码中,创建对象。  -- 正转
}

容器:是要给服务器软件,一个框架(spring)

为什么要使用ioc:目的就是减少对代码的改动,也能实现不同的功能。实现解耦合。

Java中创建对象由哪些方式:

1、构造方法,new Student()

2、反射

3、序列化

4、克隆

5、ioc:容器创建对象

6、动态代理

ioc的体现:

​ servlet 1:创建类继承HTTP Servlet

​ 2:在web.xml 注册servlet,使用的是:

<servlet-name>myservletservlet-name>
<servlet-class>com.hr.MyServletservlet-class>

​ 3:没有创建Servlet对象,没有 MyServlet myservlet = new MyServlet();

​ 4:Servlet 是Tomcat服务器它给你创建的。Tomcat也称为容器

​ Tomcat作为容器:里面存放的有Servlet对象, Listener , Filter对象

IoC的技术实现,

​ DI 是ioc的技术实现

​ DI(Dependency Injection):依赖注入,只需要在从程序中提供要使用的对象的名称就可以了,至于对象如 何在容器中创建,赋值,查找都由容器内部实现。

Spring是使用的di实现了ioc的功能,spring底层创建对象,使用的是反射机制。

spring是一个容器,管理对象,给属性赋值,底层是反射创建对象。

Spring第一个例子

使用的ioc,由spring创建对象

实现步骤:

1、创建maven项目

2、加入maven的依赖

​ spring的依赖,版本5.2.5版本

​ junit依赖

3、创建类(接口和他的实现类)

​ 和没有使用框架一样,就是普通的类

4、创建spring需要使用的配置文件

声明类的信息,这些类由spring创建和管理

5、测试spring创建的。

@Test
    public void test02(){
        //使用spring容器创建的对象
        //1.指定spring配置文件的名称
        String config="beans.xml";
        //2.创建表示spring容器的对象,ApplicationContext
        //ApplicationContext就是表示spring容器,通过容器获取对象使用对象了
        //ClassPathXmlApplicationContext:表示从类路径中加载spring的配置文件
        ApplicationContext ac=new ClassPathXmlApplicationContext(config);

        //从容器中获取某个对象,你要调用对象的方法
        //getBean("配置文件中的bean的id值")
        SomeService someService = (SomeService) ac.getBean("someService");

        //使用spring创建好的对象,调用方法
        someService.doSome();
    }

spring 默认创建对象的时间:在创建spring的容器时,会创建配置文件中的所有对象

spring创建对象:默认调用的是无参数构造方法

通过方法获取spring容器中Java对象的信息

@Test
    public void test03(){
        String config="beans.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        //使用spring 提供的方法,获取容器中定义的对象的数量
        int nums=ac.getBeanDefinitionCount();
        System.out.println("容器中定义的对象的数量"+nums);
        //使用spring提供的方法,获取容器中对象的名称,返回会是一个数组
        String[] names = ac.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }

创建非自定义的类对象

首先要在beans.xml中标签中配置

<bean id="mydate" class="java.util.Date" />

跟自定义对象不同的是,路径要写为已经写好的路径

测试非自定义类对象

@Test
    public void test04(){
        String config="beans.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        //使用getBean()
        Date mydate = (Date) ac.getBean("mydate");
        System.out.println(mydate.getTime());
    }

基于XML的DI

​ 注入:就是赋值的意思
​ 简单类型:spring中规定Java的基本数据类型和spring都是简单类型
​ di:给属性赋值
​ 1、set注入(设值注入):spring调用类的set方法,你可以在set方法中来完成属性赋值
​ 1)简单类型的set注入


​ 一个property只能给一个属性赋值

2、引用类型的set注入:spring调用类的set方法


简单类型设值注入

实例:


<bean id="myStudent" class="com.hr.qjw.ba01.Student" >
        <property name="name" value="李四" />
        <property name="age" value="21" />
    bean>

通过实体类student类中的set设置注入,通过set类中的set方法,将值赋给变量

需要实体类中必须有set方法,否则会报错

设置注入只是去调用了对应的set方法,有没有对应的属性不会报错

引用类型设值注入

实例

<bean id="myStudent" class="com.hr.qjw.ba02.Student" >
        <property name="name" value="李四" />  
        <property name="age" value="21" />  

        <property name="School" ref="mySchool" />
    bean>


    <bean id="mySchool" class="com.hr.qjw.ba02.School">
        <property name="name" value="河北软件职业"/>
        <property name="address" value="保定"/>
    bean>

构造注入

构造注入:spring调用类有参数构造方法,在创建对象的同时,在构造方法中给属性赋值。
构造注入使用 标签
标签:一个表示构造方法一个参数。
>标签属性:
name:表示构造方法的形参名
index:表示构造方法的参数的位置,参数从左往右是 0,1,2的顺序
value:构造方法的形参类型是简单类型的,使用value
ref:构造方法是引用类型的,使用ref

三种构造注入方法的实例


    <bean id="myXueXiao" class="com.hr.qjw.ba03.School">
        <property name="name" value="清华大学"/>
        <property name="address" value="北京"/>
    bean>

    <bean id="myStudent" class="com.hr.qjw.ba03.Student" >
       <constructor-arg name="myname" value="ccl" />
        <constructor-arg name="myage" value="20" />
        <constructor-arg name="myschool" ref="myXueXiao" />
    bean>

    <bean id="myStudent2" class="com.hr.qjw.ba03.Student" >
        <constructor-arg index="0" value="hxy"/>
        <constructor-arg index="1" value="19"/>
        <constructor-arg index="2" ref="myXueXiao"/>
    bean>

    <bean id="myStudent3" class="com.hr.qjw.ba03.Student" >
        <constructor-arg  value="hxy"/>
        <constructor-arg  value="19"/>
        <constructor-arg  ref="myXueXiao"/>
    bean>

前面两种的方法,bean标签里面的顺序不规定,但是第三种index省略必须要保持顺序符合index 0,1,2的顺序才可以

创建文件对象


    <bean id="myfile" class="java.io.File">
        <constructor-arg name="parent" value="D:\Project\spring-course\ch02-di-xml"/>
        <constructor-arg name="child" value="readme.txt"/>
    bean>

引用类型自动注入

使用的规则常用的是byName,byType

byName

1、byName(按名称注入):Java类中引用类型的属性名和spring容器中(配置文件)的id名称一样,
且数据类型是一致的,这样的容器中的bean,spring能够赋值给引用类型。
语法规则:

简单类型属性赋值

实例:



    <bean id="myStudent" class="com.hr.qjw.ba04.Student" autowire="byName">
        <property name="name" value="李四" />  
        <property name="age" value="21" />  


    bean>


    <bean id="school" class="com.hr.qjw.ba04.School">
        <property name="name" value="清华大学"/>
        <property name="address" value="北京"/>
    bean>

声明的对象id要与数据类型的变量名相同

byType

2、byType(类型注入):Java类中引用类型的数据类型和spring容器中(配置文件)的class属性
是同源关系的,这样的bean能够赋值给引用类型
同源就是一类的意思:
1、Java类中引用类型的数据类型和bean的class的值是一样的。
2、Java类中引用类型的数据类型和bean的class的值是父子类关系的。
3、Java类中引用类型的数据类型和bean的class的值接口和实现类关系的。
语法规则:

     <bean id="xx" class="yyy" autowire="byType">
        简单类型属性赋值
     bean>

​ 注意:在byType中,在xml配置文件中声明bean只能有一个符合条件的
​ 多余一个是错误的

实例:

1、Java类中引用类型的数据类型和bean的class的值是一样的。

    <bean id="myStudent" class="com.hr.qjw.ba05.Student" autowire="byType">
        <property name="name" value="李四" />  
        <property name="age" value="21" />  
    bean>
    
    <bean id="mySchool" class="com.hr.qjw.ba05.School">
        <property name="name" value="人民大学"/>
        <property name="address" value="北京"/>
    bean>

2、Java类中引用类型的数据类型和bean的class的值是父子类关系的。

    <bean id="myStudent" class="com.hr.qjw.ba05.Student" autowire="byType">
        <property name="name" value="李四" />  
        <property name="age" value="21" />  
    bean>
    
    <bean id="primarySchool" class="com.hr.qjw.ba05.primarySchool">
        <property name="name" value="河北软件"/>
        <property name="address" value="保定"/>

    bean>

primarySchool是School的子类,所以也可以通过自动引用注入

基于注解的DI

通过注解完成Java对象创建,属性赋值。

使用注解的步骤:

​ 1、加入maven的依赖 spring-context,在你加入spring-context的同时, 间接加入spring-aop的依赖。

​ 使用注解必须使用spring-aop依赖

​ 2、在类中加入spring的注解(多个不同功能的注解)

​ 3、在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置

​ 学习的注解:
​ 1、@Component

​ 2、@Respotory

​ 3、@Service

​ 4、@Controller

​ 5、@Value

​ 6、@Autowired

​ 7、@Resource

​ @Component:创建对象的,等同于的功能

属性:value 就是对象的名称,也就是bean的id值,

value的值是唯一的。创建的对象在整个spring的容器中就一个

位置:在类的上面

@Component(value = “myStudent”)等同于

spring中和@Component功能一致,创建对象的注解还有:

1、@Repository(用来持久层类的上面):放在dao的实现类上面,

表示创建dao对象,dao对象是能访问数据库的。

2、@Service(用在业务层类的上面):放在Service的实现类上面,

创建service对象,service对象是做业务处理,可以有事务等供你的。

3、@Controller(用在控制器的上面):放在控制器(处理器)类的上面,创建控制器对象的,

控制器对象,能够接受用户提交的参数,显示请求的处理结果

以上三个注解的使用语法和@Component一样的。都能创建对象,但是这三个注解还有额外的功能

@Repository、@Service、@Controller是给项目的对象分层的。

@Component 会用到的地方:以上三个类上面都不是的地方,而且需要创建对象的地方使用

@Component用法

使用value属性,指定对象名称

@Component(value = “myStudent”)

省略value
@Component(“myStudent”)

不指定对象名称,由spring提供默认名称:类名的首字母小写
@Component

声明组件扫描器(component-scan),组件就是Java对象

base-package:指定注解在你的项目中的包名
component-scan工作方式:spring会扫描遍历base-package指定的包
把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值。
加入了component-scan标签,配置文件的变化:
1、加入一个新的约束文件spring-context.xsd
2、给这个新的约束文件起个命名空间的名称

<context:component-scan base-package="com.hr.qjb.ba01"/>

指定多个包的三种方式


    <context:component-scan base-package="com.hr.qjb.ba01"/>
    <context:component-scan base-package="com.hr.qjb.ba02"/>


    <context:component-scan base-package="com.hr.qjb.ba01;com.hr.qjb.ba02"/>


    <context:component-scan base-package="com.hr.qjb"/>

简单类型赋值

@Value:简单类型的属性赋值

属性:value 是String类型的,表示简单类型的属性值

位置:1、在属性定义的上面,无需set方法,推荐使用

​ 2、在set方法的上面

  	//用在属性上
	@Value(value = "小龙女")
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }
	//用在set上
    @Value("2323")
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';

引用类型赋值

@Autowired:spring框架提供的注解,实现应用类型的赋值。

spring中通过注解给引用类型赋值,使用的是自动注入原理,支持byName,byType

@Autowired:默认使用的是byType自动注入

位置:1、在属性定义的上面,无需set方法,推荐使用

​ 2、在set方法的上面

引用类型byType注入

@Component("mySchool")
public class School {
    @Value("河北软件")
    private String name;
    @Value("保定")
    private String address;

    public void setName(String name) {
        this.name = name;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

首先要用@Component给这个类型创建对象

    @Autowired
    private School school;

之后在定义的属性上面加上注解@Autowired 因为默认是byType类型注入,则会去找与之类型相同的类注入

引用类型byName注入

如果要使用byName方式,需要做的是:

​ 1、在属性上面加入@Autowired

​ 2、在属性上面加入@Qualifier(value=“bean的id”):表示使用指定名称的bean完成赋值。

@Autowired
@Qualifier("mySchool")
private School school;

@Autowired意思为要自动找,@Qualifier是按byName去查找类

@Autowired的属性:

属性:required ,是要给boolean类型的默认true

required=true :表示引用类型赋值失败,程序报错,并终止执行。

required=false :引用类型如果赋值失败,程序正常执行,引用类型是null

推荐为true,因为如果找不到的时候会报错,这样可以及时调试,不让漏洞太大

@Resource

@Resource:来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值

使用的也是自动注入原理,支持byName,byType,默认是byName

位置:1、在属性定义的上面,无需set方法,推荐使用

​ 2、在set方法的上面

    @Resource
    private School school;

如果byName找不到,则会使用byType去找

@Resource只是用byName方式,需要增加一个属性name

name的值是bean的id(名称)

    @Resource(name = "mySchool")
    private School school;

xml配置文件和注解的对比

如果经常改则尽量使用xml配置文件,因为只需要去改一下配置文件,而不需要去改代码

如果不会经常去改则可以使用注解

junit

junit:单元测试,一个工具类库,做测试方法使用的。

​ 单元:指定的是方法,一个类中有很多方法,一个方法称为单元。

​ 使用单元测试:
​ 1、需要加入junit依赖

<dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.11version>
      <scope>testscope>
    dependency>

​ 2、创建测试用作用的类:叫做测试类

​ src/test/java目录中创建类

​ 3、创建测试方法

​ 1)public方法

​ 2)没有返回值 void

​ 3)方法名称自定义,建议名称是test+你要测试方法名称

​ 4)方法没有参数

​ 5)方法的上面加入@Test,这样的方法是可以单独执行的,不用使用main方法

多个配置优势

1、每个文件的大小比一个文件要小很多,效率高

2、避免多人竞争带来的冲突。

如果你的项目有多个模块(相关的功能在一起),一个模块一个配置文件。

学生考勤模块一个配置文件 ,张三

学生成绩一个配置文件, 李四

多文件的分配方式:
1、按功能模块,一个模块一个配置文件

2、按类的功能,数据库相关的配置一个文件配置文件,做事务的功能一个配置文件,做service功能的一个配置文件等

包含关系的配置文件:

spring-total表示主配置文件:包含其他的配置文件的。主配置文件一般是不定义对象的

语法:

关键字:“classpath:” 表示类路径(class文件所在的目录),在spring的配置文件中要指定其他文件的位置

需要使用classpath,告诉spring到哪去加载读取文件

实例:


<import resource="classpath:ba06/spring-school.xml"/>
<import resource="classpath:ba06/spring-student.xml" />

    
<import resource="classpath:ba06/spring-*.xml" />

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L72JBT49-1629774381245)(image\多个配置文件.png)]

多个配置文件的时候,可以设置一个主配置文件,去定义其他配置文件都属于哪个模块

学生成绩一个配置文件, 李四

多文件的分配方式:
1、按功能模块,一个模块一个配置文件

2、按类的功能,数据库相关的配置一个文件配置文件,做事务的功能一个配置文件,做service功能的一个配置文件等

包含关系的配置文件:

spring-total表示主配置文件:包含其他的配置文件的。主配置文件一般是不定义对象的

语法:

关键字:“classpath:” 表示类路径(class文件所在的目录),在spring的配置文件中要指定其他文件的位置

需要使用classpath,告诉spring到哪去加载读取文件

实例:


<import resource="classpath:ba06/spring-school.xml"/>
<import resource="classpath:ba06/spring-student.xml" />

    
<import resource="classpath:ba06/spring-*.xml" />

多个配置文件的时候,可以设置一个主配置文件,去定义其他配置文件都属于哪个模块

你可能感兴趣的:(java,spring,ioc)