Spring(一)---IOC(控制权反转)

目录

引入

[1.什么叫IOC(Inversion of Control)控制权反转?](#1.什么叫IOC(Inversion of Control)控制权反转?)

[2.什么叫AOP(Aspect-Oriented Programming)面向切面编程(涉及Java代理)?](#2.什么叫AOP(Aspect-Oriented Programming)面向切面编程(涉及Java代理)?)

3.简单谈一下Java怎么实现ICO?

Spring框架的介绍

[1. Spring框架的概述](#1. Spring框架的概述)

[2. Spring框架的优点](#2. Spring框架的优点)

[Spring IOC容器介绍](#Spring IOC容器介绍)

[1. 什么是IOC](#1. 什么是IOC)

[2. IOC容器的底层原理(详细)](#2. IOC容器的底层原理(详细))

3.IOC(接口)

一、xml配置形式实现--创建对象

1.配置一个项目搭建Spring框架

2.将项目配置成Spring框架

[3. 编写类](#3. 编写类)

4.创建Test类去实现(一般方法)

5.用Spring框架去实现

二、xml配置形式实现--注入属性

1.get/set的方式--注入属性

[2. 构造函数方法--注入属性](#2. 构造函数方法--注入属性)


引入

Spring框架主要围绕这两点展开:

1.什么叫IOC(Inversion of Control)控制权反转?

回答这个问题之前,先回答一个问题,在Java中如何创建一个对象?答案有"new 关键字"、"反射"等等,但是它们都有一个共性---程序员来创建Java对象。

那么所谓控制权反转,就是将这个创建Java对象的权力交给Spring管理。

2.什么叫AOP(Aspect-Oriented Programming)面向切面编程(涉及Java代理)?

简而言之,就是在不改变源代码的基础上,对代码的功能进行加强。

3.简单谈一下Java怎么实现ICO?

如下流程图:

通过Spring框架来创建对象,本质来说,就是通过一张Spring里面的xml配置表,里面装载了所能创建对象的路径,并且Spring框架封装了上面有关反射的main函数,通过反射的方式帮助我们创建对象。

Spring框架的介绍

1. Spring框架的概述

Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。

Spring是于2003 年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE.

Development and Design中阐述的部分理念和原型衍生而来。

它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

**Spring的核心是控制反转(IOC)和面向切面(AOP)。**简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。

IOC:控制反转,将创建对象的过程交给spring进行管理.

AOP:面向切面,在不修改源代码的情况之下进行代码功能的增强.

2. Spring框架的优点

方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理,这也是IOC的作用。

AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。

声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。

方便程序的测试,Spring对Junit4支持,可以通过注解方便的测试Spring程序。

方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis等)的直接支持。

降低JavaEE API的使用难度,Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。

Spring IOC容器介绍

1. 什么是IOC

IOC -- Inverse of Control,控制反转,将对象的创建权力反转给Spring框架!

在java当中一个类想要使用另一个类的方法,就必须在这个类当中创建这个类的对象,那么可能会出现如下情况, 比如A类当中创建着B对象,B类当中有C对象,C类当中有A对象,这个如果一个类出了问题,那么可能会导致这个框架出现问题。 Spring 将创建对象的权利给了IOC,在IOC当中创建了ABC三个对象吗,那么我们我们其他的类只需要调用集合, 大大的解决了程序耦合性的问题

2. IOC容器的底层原理(详细)

IOC的实现,依赖于以下3门技术

① dom4j解析xml文档;

② 工厂模式;

③ 采用反射设计模式创建对象

首先我们需要讲一下什么是工厂模式

在当前情况之下A类想要调用B类就必须自己在自己的内部新建B类的对象,这样的耦合度太高,那我们如何降低耦合度的呢?

创建一个工厂类,这样就能够使得A和B的耦合度降低到最小值。

那么上边提到的三种技术如何实现IOC的呢?

第一步:xml配置文件,配置创建对象

html 复制代码
<bean id="demo" class="com.qcby.service.Demo" />

第二步:创建工厂类

java 复制代码
public class DemoFactory {
    //利用dom4j得到name所对应的value值
   public static Demo getDemo() throws Exception {
       //利用dom4j得到name所对应的value值
       String value="class路径";
       //通过反射创建对象
       Class clazz = Class.forName(value);
       //返回并创建demo对象
       return (Demo) clazz.newInstance();
   }
}

通过以上两步,我们基本上就可以得到我们所创建的对象。

3.IOC(接口)

1.IOC思想是基于IOC容器完成的,IOC的底层就是对象工厂

2.Spring里边提供了IOC容器的实现的两种方式

(1)BeanFactroy:IOC容器是Spring内部的使用接口,不提供给开发人员使用

* BeanFactroy:加载配置文件的时候不会去创建对象,在使用对象的时候才会去创建对象

(2)ApplicationContext:BeanFactory接口的子接口,提供了更多更强大的功能,一般由开发人员进行使用

*加载配置文件的时候会把对象创建

接下来,我们来实现以下功能:

一、xml配置形式实现--创建对象

1.配置一个项目搭建Spring框架

创建一个新项目,选择Maven后点击下一步:

设置name,可以改变工作坐标(不必要),点击完成:

2.将项目配置成Spring框架

进入项目后在如下位置导入代码:

导入坐标依赖:

html 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

第一次导入可能会弹出错误,点击这里的m导入即可:

3. 编写类

在这里编写一个类:

4.创建Test类去实现(一般方法)

(下面是一个人为创建类对象并调用类中方法的Java文件)

**注:**其中 @org.junit.Test 这个注解可以用于任何公共的、无返回值的(void)方法,用于执行针对代码的单元测试

5.用Spring框架去实现

首先在resource里面新建一个Spring配置文件:

在新建的文件里面配置如下代码:

(将类Cat的路径写进来,同时为这个类命名cat)

Test文件中编写:

java 复制代码
 @org.junit.Test
    public void test2(){
        ApplicationContext context=new ClassPathXmlApplicationContext("Spring.xml");//这里面写的是xml文件的名字
        Cat cat01=(Cat) context.getBean("cat");//这里面的"cat"对应xml文件中id对应的名称
        //将context.getBean("cat")转换成对应的类文件,这里是Cat类,接着这个被创建出来的cat01就能正常当作类实例使用了
        cat.eat();
    }

二、xml配置形式实现--注入属性

1.get/set的方式--注入属性

一个Demo类:

java 复制代码
package com.qcby.service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class Demo {
    //普通属性
    private int age;
    private String name;
    //引用属性
    private Cat cat;
    //特殊属性
    private List<String> list;
    private Map<String,Integer> map;
    private String[] strings;

    //接下来生成get/set方法和toString方法


    @Override
    public String toString() {
        return "Demo{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", cat=" + cat +
                ", list=" + list +
                ", map=" + map +
                ", strings=" + Arrays.toString(strings) +
                '}';
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Map<String, Integer> getMap() {
        return map;
    }

    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }

    public String[] getStrings() {
        return strings;
    }

    public void setStrings(String[] strings) {
        this.strings = strings;
    }

    public void run(){
        System.out.println("快跑!");
    }
}

我们就去xml中实现这些属性的注入:

html 复制代码
<?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">

    <bean id="demo" class="com.qcby.service.Demo">
        <!--使用property完成属性注入
        name:类里面属性名称
        value:向属性注入值
        ref:对象映射-->

        <!--基础类型-->
        <property name="age" value="18"/>
        <property name="name" value="张三"/>
        <!--类类型-->
        <property name="cat" ref="cat"/>
        <!--复杂类型list-->
        <property name="list">
            <list>
                <value>光头大强</value>
                <value>光头中强</value>
                <value>光头小强</value>
            </list>
        </property>
        <!--复杂类型数组-->
        <property name="strings">
            <array>
                <value>熊大</value>
                <value>熊中</value>
                <value>熊小</value>
            </array>
        </property>
        <!--复杂类型Map-->
        <property name="map">
            <map>
                <entry key="小猫" value="3"/>
                <entry key="中猫" value="12"/>
                <entry key="半挂" value="20"/>
            </map>
        </property>
    </bean>

    <bean id="cat" class="com.qcby.service.Cat"/>
</beans>

上述注入还可以在Test方法中打印toString()方法:

2. 构造函数方法--注入属性

一个Cat类:

java 复制代码
package com.qcby.service;

public class Cat {
    private String name;
    private Double age;

    //生成构造函数和toString()方法
    public Cat(String name, Double age) {
        this.name = name;
        this.age = age;
    }

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


    public void eat(){
        System.out.println("小猫爱吃罐罐");
    }
}

我们就去xml中实现这些属性的注入:

【这里只举例了两个普通版本的,但是用构造函数和用get/set方法实现并无太大差别,唯一不同就是get/set方法时用property,但是使用构造函数时用constructor-arg】

html 复制代码
<bean id="cat" class="com.qcby.service.Cat">
        <constructor-arg name="age" value="1.0"/>
        <constructor-arg name="name" value="胖小"/>
 </bean>

Test测试(同样可行):

相关推荐
LI JS@你猜啊2 分钟前
MySQL 集群
java·数据库·mysql
--地平线--13 分钟前
如何将 Java 微服务引入云
java·开发语言·微服务
柔弱女子爱java23 分钟前
spring专题笔记(五):依赖注入--p命名空间注入、c命名空间注入、util命名空间
java·笔记·后端·spring·架构·系统架构
南宫生24 分钟前
力扣-图论-18【算法学习day.68】
java·学习·算法·leetcode·图论
Random_index26 分钟前
#Java篇:java项目init和写接口流程步骤详细
java
chengma_09090939 分钟前
elasticsearch 7.6.2版本即使使用wildcard模糊查询,也毫无过滤效果分析
java·服务器·前端
“抚琴”的人43 分钟前
C#—扩展方法
java·开发语言·c#
静心观复1 小时前
快速排序算法
java
StarRocks_labs1 小时前
深入解析 StarRocks 物化视图:全方位的查询改写机制
java·大数据·数据库·sql
武子康1 小时前
Java-31 深入浅出 Spring - IoC 基础 启动IoC XML与注解结合的方式 配置改造 applicationContext.xml
java·大数据·spring·mybatis·springboot