• Spring复习之——IoC和AOP


    1.Spring框架是什么?

    简介:

    Spring就像是整个项目中装配bean(对象)的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地new一个对象,而是让Spring框架帮你来完成这一切。(包括:对象的创建、对象之间的关系)

    总结:Spring框架,可以理解为是一个管理者:管理整个分层架构(MVC)中的每一个对象;(每一个对象称之为bean)

    2.Spring框架的优缺点

    2.1优点

    • 轻量:Spring 框架运行占用的资源少,运行效率高。不依赖其他 jar
    • 针对接口编程,解耦合:Spring 提供了 Ioc 控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。
    • AOP 编程的支持:通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。
    • 方便集成各种优秀框架:Spring提供了对各种优秀框架(如 Struts,Hibernate、MyBatis)等的直接支持。简化框架的使用。Spring 像插线板一样,其他框架是插头,可以容易的组合到一起。

    2.2缺点

    • 最大的缺点就是:配置繁琐,启动慢
    • 经常要考虑第三方工具的兼容性
    • 项目的依赖管理耗时耗力

    3.框架学习什么?

    Spring最主要的学习内容:两个核心Ioc+Aop
    Spring框架是一个软件,其它人写好的软件,所以我们要掌握的就是:

    • 1.IOC :Inversion Of Control 控制反转
      2.DI:Dependency Injection 依赖注入: 本质就是给属性赋值
      DI是依附在IOC的基础上 才得以实现
      3.AOP Aspect Oriented Programming 面向切面的编程
    • 知道框架能做什么, mybatis–访问数据库, 对表中的数据执行增删改查。
    • 框架的语法, 框架要完成一个功能,需要一定的步骤支持的,
    • 框架的内部实现, 框架内部怎么做。 原理是什么。
    • 通过学习,可以实现一个框架

    4.Spring框架做什么?

    目的:管理对象

    Spring的核心思想是IOC(控制反转),把对象的控制权给了Spring,(底层是通过反射)即:不再需要程序员去显式地new一个对象,而是让Spring框架帮你来完成这一切。

    IOC控制反转:(Inversion Of Control),即就是:将对象的控制权从自己new改为跟Spring要;
    • 最常见的方式:DI:依赖注入Dependency Injection;
    • 还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

    5.Spring之IoC

    5.1核心概念

    • IoC (Inversion of Control) :控制反转, 是一个理论,概念,思想。描述的:把对象的创建,赋值,管理工作都交给代码之外的容器实现, 也就是对象的创建是有其它外部资源完成。目的就是减少对代码的改动, 也能实现不同的功能。 实现解耦合。
      • 控制: 创建对象,对象的属性赋值,对象之间的关系管理。
      • 反转: 把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。 由容器代替开发人员管理对象。创建对象,给属性赋值。
      • 正转:由开发人员在代码中,使用new 构造方法创建对象, 开发人员主动管理对象。
    • 容器:是一个服务器软件, 一个框架(spring就是一个容器,帮我们创建对象,管理对象之间的关系)

    5.2 IoC的技术实现

    DI 是ioc的技术实现

    • DI(Dependency Injection):依赖注入, 只需要在程序中提供要使用的对象名称就可以, 至于对象如何在容器中创建,赋值,查找都由容器内部实现。
    • spring是使用的di实现了ioc的功能, spring底层创建对象,使用的是反射机制。因此只需要传一个类名,Spring就可以创建对象。
    • spring是一个容器,管理对象,给属性赋值, 底层是反射创建对象。

    5.3 完成IoC的步骤

    在这里插入图片描述

    1. 添加依赖。
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-contextartifactId>
        <version>5.2.5.RELEASEversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.创建类、接口、实现类。Spring在MVC三层架构中是针对service层的框架。

    ​ 3.Spring配置文件。通常命名为:applicationContext.xml。该文件类似Servlet的web.xml,在配置文件中注册类,这样Spring才能完成IOC

    
    <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">
    
        
        <bean id="someService" class="com.xd.service.impl.SomeServiceImpl">bean>
    
        
        <bean id="someService1" class="com.xd.service.impl.SomeServiceImpl" scope="prototype">bean>
    
        
        <bean id="myDate" class="java.util.Date">bean>
    beans>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    4. 测试类中创建Spring容器,调用Spring容器中的方法可以创建对象、获取对象的信息。

    @Test
    public void test02(){
        //使用spring容器创建的对象
        //1.指定spring配置文件的名称
        String config="applicationContext.xml";
        //2.创建表示spring容器的对象, ApplicationContext
        // ApplicationContext就是表示Spring容器,通过容器获取对象了
        // ClassPathXmlApplicationContext:表示从类路径中加载spring的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
    
        //从容器中获取某个对象, 你要调用对象的方法
        //getBean("配置文件中的bean的id值")
        SomeService service = (SomeService) ac.getBean("someService");
    
        //使用spring创建好的对象
        service.doSome();
    }
    
    /*
    以下代码的执行原理:通过ClassPathXmlApplicationContext创建容器对象,创建容器对象的同时,ClassPathXmlApplicationContext会根据配置文件的路径去解析配置文件,解析的过程会将配置文件中所有标签中的类创建对象,默认调用无参构造方法,之后将创建好的对象以及bean标签的id保存在map中,其中id为key。在测试文件中可以调用容器对象ac的getBean方法通过id获取创建好的对象,要强转,然后调用对应方法。
    */
    public void test06(){
    	String path = "applicationContext.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(path);
        Date nowTime = (Date)ac.getBean("myDate");
        System.out.println(nowTime);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    注意:

    • ApplicationContext是一个接口,有多个实现类,通常使用ClassPathXmlApplicationContext。
    • spring默认创建对象的时间:创建spring的容器时,会创建配置文件中的所有的对象。并把这些对象放到springMap中,之后通过bean标签中的id获取创建好的对象 spring创建对象:默认调用的是无参数构造方法。

    5.4 Spring容器对象的方法

    //创建容器对象
    ApplicationContext ac = new ClassPathXmlApplicationContext(config);
    //根据bean标签的id获取创建好的对象,getBean返回Object类型,要强转。通过service调用该类的方法
    SomeService service = (SomeService) ac.getBean("someService");
    //获取容器中定义的对象的数量
    int nums = ac.getBeanDefinitionCount();
    //容器中每个定义的对象的名称,知道了对象的名称,就可以通过getBean获取创建好的对象。
    String[] names = ac.getBeanDefinitionNames();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.5 IoC的依赖注入:DI

    • 依赖就是属性,注入就是赋值。
    • 注入的方式有set注入以及构造注入,也就是对应正转里的通过类的set方法给对象赋值,以及通过构造方法给类属性赋值。
    • 使用set注入,Spring是根据属性名去寻找对应的set方法并执行,与有没有属性,set方法中写什么内容无关。Spring只是负责找到set方法并执行。set注入也分为简单类型的注入以及引用类型的注入。
      在这里插入图片描述

    具体实现:

     
    <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"
      
    	
        
        <bean id="myStudent" class="com.xd.ba02.Student">
            <property name="name" value="张三"/>
            <property name="age" value="20"/>
            <property name="email" value="zhangsan@qq.com"/>
            
            <property name="school" ref="mySchool"/>
        bean>
    
        
        <bean id="mySchool" class="com.xd.ba02.School">
            <property name="name" value="西安电子科技大学"/>
            <property name="address" value="西安市雁塔区"/>
        bean>
        
        
        <bean id="myStudent" class="com.xd.ba03.Student">
            
            <constructor-arg name="name" value="张三"/>
            <constructor-arg name="age" value="20"/>
            <constructor-arg name="school" ref="mySchool"/>
        bean>
    
        
        <bean id="myStudent1" class="com.xd.ba03.Student">
            <constructor-arg index="0" value="李四"/>
            <constructor-arg index="1" value="22"/>
            <constructor-arg index="2" ref="mySchool"/>
        bean>
    
        
        <bean id="myStudent2" class="com.xd.ba03.Student">
            <constructor-arg value="李四"/>
            <constructor-arg value="22"/>
            <constructor-arg ref="mySchool"/>
        bean>
    
        
        <bean id="mySchool" class="com.xd.ba03.School">
            <property name="name" value="西安xxx大学"/>
            <property name="address" value="西安市雁塔区"/>
        bean>
    
        
        
        <bean id="myFile" class="java.io.File">
            <constructor-arg name="parent" value="F:\计算机\Java学习\SSM\04-Spring\源码\ch02-di-xml"/>
            <constructor-arg name="child" value="readme.txt"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    5.6 基于注解的di(重点)

    • 基于注解的di: 通过注解完成java对象创建,属性赋值
    • 使用注解的步骤:
      1. 加入maven的依赖 spring-context ,在你加入spring-context的同时, 间接加入spring-aop的依赖。使用注解必须使用spring-aop依赖
      2. 在类中加入spring的注解(多个不同功能的注解)
      3. 在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置
    • 组件扫描器(component-scan):组件就是java对象。使用方式实在spring配置文件中引入组件扫描器。
    
    <context:component-scan base-package="com.xd.ba01"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 学习的注解:@Component、@Respotory、@Service、@Controller、@Value、@Autowired、@Qualifier、@Resource

    5.6.1 @Component注解

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

    • 语法格式:@Component(value = “myStudent”) 等同于
      • 属性:value 就是对象的名称,也就是bean的id值,value的值是唯一的,创建的对象在整个spring容器中就一个;
      • 位置:在类的上面
    //使用value属性,指定对象名称
    //@Component(value = "myStudent")
    //不指定对象名称,由spring提供默认名称: 类名的首字母小写
    //@Component
    
    @Component("myStudent")  //常用
    public class Student {
        private String name;
        private int age;
    
        public Student() {
            System.out.println("student无参构造方法执行");
        }
    
    	setter
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5.6.2 @Respotory、@Service、@Controller 注解

    • @Respotory、@Service、@Controller这三个注解与Component功能类似,都是创建对象。但是又有其特殊的用途,是给项目的对象分层的。
    • @Repository(用在持久层类的上面) : 放在dao的实现类上面,表示创建dao对象,dao对象是能访问数据库的。
    • @Service(用在业务层类的上面):放在service的实现类上面,创建service对象,service对象是做业务处理,可以有事务等功能的。
    • @Controller(用在控制器的上面):放在控制器(处理器)类的上面,创建控制器对象的,控制器对象,能够接受用户提交的参数,显示请求的处理结果。
    • 对于@Component、@Respotory、@Service、@Controller。毋庸置疑的是,持久层dao用@Respotory、业务层用@Service、页面层用@Controller。对于其它不在这三层的类,但是又想创建对象,就用@Component注解。

    5.6.3 @Value

    • @Value注解的作用是给对象简单类型属性赋值
    • 属性:@Value注解里的值必须是String类型,赋的值要用双引号括起来
    • 位置:
      1. 在属性定义的上面,无需set方法,推荐使用。底层用反射快。
      2. 在set方法的上面使用,调set方法。
    @Component("myStudent")
    public class Student {
        @Value("张三")
        private String name;
        
        @Value("20")
        private int age;
        
        //@Value("20") 调set方法
        public void setAge(int age) {
            System.out.println("student的set方法执行了");
            this.age = age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.6.4 @Autowired

    • @Autowired注解的作用是给对象引用类型属性赋值。使用的是自动注入原理 ,支持byName, byType。默认byType。

    • 位置:

      1. 在属性定义的上面,无需set方法, 推荐使用
      2. 在set方法的上面
      @Autowired  //按byType注入
      private School school;
      
      • 1
      • 2
    • 如果要使用byName方式,需要做的是:

      1. 在属性上面加入@Autowired
      2. 在属性上面加入@Qualifier(value=“bean的id”) :表示使用指定名称的bean完成赋值。
      @Component("mySchool")
      public class School {
      }
      
      @Autowired
      @Qualifier(value = "mySchool") //mySchool为id
      private School school;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • @Autowired注解的request属性,是一个boolean类型的,默认true。一般使用true,方便排错。

      • required=true:表示引用类型赋值失败,程序报错,并终止执行。
      • required=false:引用类型如果赋值失败, 程序正常执行,引用类型是null,不建议用,因为赋值为null以后会出空指针异常。
      //@Autowired(required = true) 默认
      //@Autowired(required = false)不报错,不建议用
      @Autowired
      @Qualifier(value = "mySchool")
      private School school;
      
      • 1
      • 2
      • 3
      • 4
      • 5

    5.6.5 @Resource

    • @Resource: 来自jdk中的注解,spring框架提供了对这个注解的功能支持,完成引用类型的自动注入,支持byName,byType。默认byName

    • 位置:

      1. 在属性定义的上面,无需set方法,推荐使用。
      2. 在set方法的上面
      @Component("school")
      public class School {
      }
          
      @Resource //默认是byName: 先使用byName自动注入,如果byName赋值失败,再使用byType
      private School school;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • @Resource只使用byName方式,需要增加一个属性 name,name的值是bean的id(名称)

      @Resource(name = "mySchool")
      private School school;
      
      • 1
      • 2
  • 相关阅读:
    hudi系列-changelog的读写
    day22_mysql
    1. 关于pytorch中的数据操作的广播机制
    每日三题 8.19
    zabbix企业监控
    C++之多态以及文件处理
    regexpire-攻防世界-MISC
    LabVIEW合并VI
    (pytorch进阶之路)扩散概率模型
    计算机毕业论文Java项目源码下载基于SSM实现的客户信息管理系统
  • 原文地址:https://blog.csdn.net/m0_48904153/article/details/126257919