这份Sping IOC学习笔记你真得好好看看,阿里大牛花了三天整理出来的

Sping 的简介

Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。

Spring的特点

1.Spring是一个开源的免费框架(容器)
2.Spring是一个轻量级、非入侵式的框架
3.控制反转(IOC)面向切面编程(AOP)核心
4.支持事务的处理,对框架整合

使用Spring

我们在maven的项目中只需要导入spring-webmvc架包,maven会自动为我们导入其他的依赖架包

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.8.RELEASE</version>
    </dependency>

Sping的七大核心模块

核心容器(Spring Core)

核心容器提供Spring框架的基本功能。Spring以bean的方式组织和管理Java应用中的各个组件及其关系。Spring使用BeanFactory来产生和管理Bean,它是工厂模式的实现。BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的应用程序代码分开。

应用上下文(Spring Context)

Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,如JNDI、EJB、电子邮件、国际化、校验和调度功能。

Spring面向切面编程(Spring AOP)

通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring框架中。所以,可以很容易地使 Spring框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

JDBC和DAO模块(Spring DAO)

JDBC、DAO的抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理,和不同数据库供应商所抛出的错误信息。异常层次结构简化了错误处理,并且极大的降低了需要编写的代码数量,比如打开和关闭链接。

对象实体映射(Spring ORM)

Spring框架插入了若干个ORM框架,从而提供了ORM对象的关系工具,其中包括了Hibernate、JDO和 IBatis SQL Map等,所有这些都遵从Spring的通用事物和DAO异常层次结构。

Web模块(Spring Web)

Web上下文模块建立在应用程序上下文模块之上,为基于web的应用程序提供了上下文。所以Spring框架支持与Struts集成,web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

MVC模块(Spring Web MVC)

MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的。MVC容纳了大量视图技术,其中包括JSP、POI等,模型来有JavaBean来构成,存放于m当中,而视图是一个街口,负责实现模型,控制器表示逻辑代码,由c的事情。Spring框架的功能可以用在任何J2EE服务器当中,大多数功能也适用于不受管理的环境。Spring的核心要点就是支持不绑定到特定J2EE服务的可重用业务和数据的访问的对象,毫无疑问这样的对象可以在不同的J2EE环境,独立应用程序和测试环境之间重用。

Sping三大核心思想

DI(依赖注入) :后台需要对象时,spring容器将给后台空对象以bean的方 式注入对象
IOC(控制反转) :后台对象由主动创建变被动接受,权限发生了转移
AOP(面向切面编程):在整个系统中,动态横向添加新的功能,还不改变原来业务流程的编码。 那么横向扩展怎么理解呢,我们在WEB项目开发中,通常都遵守三层原则:
包括控制层(Controller)->业务层(Service)->数据层(dao),那么从这个结构下来的为纵向,它具体的某一层就是我们所说的横向。(AOP是OOP的补充)

IOC创建对象

创建Spring的xml配置applicationContext.xml
可以参考官方文档Sping官方文档

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->
</beans>

Hello.java

package com.zx.hello;

/**
 * @Author Tim
 * @Date 2020/7/22 22:43
 * @Version 1.0
 */
public class Hello {
    private String hello;


    public String getHello() {
        return hello;
    }
     //set方法在这里是什么关键的(由set方法来注入对象的),没有Set方法就会报错 
    public void setHello(String hello) {
        this.hello = hello;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "hello='" + hello + '\'' +
                '}';
    }
}

以前创建对象:

Hello hello = new Hello();

现在在Sping配置文件中(前提是要保证Hello这个类必须存在):
id = 变量名 – hello
class = new Hello();
bean = 对象
property = 对象属性值

<?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来创建对象,在Spring中统一叫做Bean-->
    <!--    该id属性是标识单个bean定义的字符串。
            该class属性定义Bean的类型,并使用完全限定的类名。
            该id属性的值是指协作对象。在此示例中未显示用于引用协作对象的XML
     -->

    <!--
        bean = 对象
        Hello hello = new Hello();

        id = 变量名
        class =  new 的对象
        property  相当于给对象中的属性设值
    -->
        <bean id="hello" class="com.zx.hello.Hello">
            <!--给对象属性设值-->
            <property name="hello" value="spring"></property>
            <!-- collaborators and configuration for this bean go here -->
            <!--ref是引用Spring容器中创建好的对象-->
            <!--<property name="xx" ref="conversionService"></property>-->
        </bean>
   </beans>

然后便可以在Java实现类中调用对象(sping 容器一加载对象就创建了)

//获取Spring上下对象(获取Spring容器)
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
//到此我们的对象就在Spring中管理了,我们要使用就直接去拿就好了。
Hello hello = (Hello) ac.getBean("hello");
Hello hello = ac.getBean("hello",Hello.class);

IOC创建对象的方式

使用无参构造创建对象(默认)
使用有参构造创建对象(如下)
    <bean id="user1" class="com.zx.user.Users">
        <!--index对象属性下标  下标赋值-->
        <constructor-arg index="0" value="李四"></constructor-arg>
    </bean>
     
    <!-- 不建议使用 当有多个相同类型就went  类型-->
    <bean id="user2" class="com.zx.user.Users">
        <constructor-arg type="java.lang.String" value="王五"></constructor-arg>
    </bean>

    <!-- 直接通过参数名-->
    <bean id="user3" class="com.zx.user.Users">
        <constructor-arg name="name" value="董彬"></constructor-arg>
    </bean>

DI(依赖注入)

依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性值由容器注入
1.构造器注入(前面)

2.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">

    <bean id="home" class="com.zx.Home">
        <property name="home" value="安徽宣城"></property>
    </bean>
    <bean id="student" class="com.zx.Student">
        <property name="name" value="黄杰"></property>
        <property name="home" ref="home"/>
        <property name="books">
          <array>
              <value>西游记</value>
              <value>水浒传</value>
              <value>三国演义</value>
              <value>红楼梦</value>
          </array>
        </property>
        <property name="hobbys">
            <list>
                <value>多人运动</value>
                <value>篮球</value>
            </list>
        </property>

        <property name="cards">
            <map>
                <entry key="身份证" value="111111111111"></entry>
                <entry key="银行卡" value="23456s"></entry>
            </map>
        </property>

        <property name="games">
            <set>
                <value>王者荣耀</value>
                <value>刺激战场</value>
            </set>
        </property>
        <property name="info">
            <props>
                <prop key="学号">16014420048</prop>
                <prop key="姓名">大黄</prop>
            </props>
        </property>
        <property name="wrok">
            <null></null>
        </property>
    </bean>
</beans>

3.其他注入

   <?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:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--需要在USER类里添加无参构造器
       p命名空间对应就是set的属性注入property
    -->
    <bean id="user1" class="com.obj.User" p:name="张三" p:age="18" scope="prototype"></bean>

    <!--需要在USER类里添加有参构造器
      c命名空间对应就是构造器注入-->
    <bean id="user2" class="com.obj.User" c:name="李四" c:age="20"></bean>

    <!--p 和 c命名空间不可以直接使用,要导入XML约束-->
    <!--scope作用域,bean的作用域 默认是单例模式singleton  原型模式prototype
     其余的在Web开发使用request、session、application
     -->
</beans>
p 和 c命名空间不可以直接使用,要导入XML约束
<!--scope作用域,bean的作用域 默认是单例模式singleton  原型模式prototype
 其余的在Web开发使用request、session、application
-->

IOC的本质

IOC(控制反转),他是一中设计思想!IOC的本质就是获得依赖对象的方式反转了,使程序不要再去管理对象的创建,使得程序的耦合大大降低,可以将对象的创建交给第三方。
控制反转就是通过描述(xml配置文件、注解)通过第三方去产生或者获取到对象的方式,在Sping中IOC容器实现了控制反转,其实现的方法便是DI(依赖注入)。

补充(自动装配)

Bean的自动装配
自动装配是Spring是满足bean依赖的一种方式,Sping会在上下文中自动寻找,并自动给bean装配属 性。spring中有三种装配方式:
1.xml中显示配置
2.在java中显示配置
3.隐式的自动装配(***)

方式一:

<?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="cat" class="com.zx.Cat">
        <property name="name" value="猫因"/>
    </bean>

    <bean id="dog" class="com.zx.Dog">
        <constructor-arg name="name" value="豆豆"/>
    </bean>

    <bean id="people" class="com.zx.People">
        <property name="name" value="大黄"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>

    <!--自动装配-->
    <!-- byName 会自动在容器中寻找和自己对象set方法后面的值对应的bean  id-->
    <bean id="people1" class="com.zx.People" autowire="byName">
        <property name="name" value="亚飞"/>
    </bean>

    <!-- byType 会自动在容器中寻找和自己对象类型相同的bean  id-->
    <bean id="people2" class="com.zx.People" autowire="byType">
        <property name="name" value="董小姐"/>
    </bean>

</beans>
import com.zx.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author Tim
 * @Date 2020/7/23 17:12
 * @Version 1.0
 */
public class Test6 {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        People people = ac.getBean("people",People.class);
        people.getCat().show();
        people.getDog().show();
        System.out.println("这个人叫"+people.getName());


        People people1 = ac.getBean("people1",People.class);
        people1.getCat().show();
        people1.getDog().show();
        System.out.println("这个人叫"+people1.getName());


        People people2 = ac.getBean("people2",People.class);
        people2.getCat().show();
        people2.getDog().show();
        System.out.println("这个人叫"+people2.getName());


    }
}

方式二、

使用JAVA的方式来配置Spring
完全不用Spring的XML配置了
JavaConfig是Spring的一个子项目,在Spring4之后变为一个核心功能

@Configuration代表是一个配置``类,就和我们之前的bean.xml一样

@ComponentScan("com.zx")扫描包

@Bean//注册一个bean就相当于bean标签,方法名字就是id,返回值就是class属性
package com.config;

import com.zx.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @Author Tim
 * @Date 2020/7/24 17:51
 * @Version 1.0
 */
@Configuration//这个也会被容器托管,注册到容器中,因为他本就是一个@Component
@ComponentScan("com.zx")//不写也可以
public class UserConfig {
    @Bean//注册一个bean就相当于bean标签,方法名字就是id,返回值就是class属性
    public User getUser(){
        return new User();
    }
}

package com.zx;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @Author Tim
 * @Date 2020/7/24 17:48
 * @Version 1.0
 */
@Component
public class User {
    private String name;

    public String getName() {
        return name;
    }
    @Value("张三")
    public void setName(String name) {
        this.name = name;
    }

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

import com.config.UserConfig;
import com.zx.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @Author Tim
 * @Date 2020/7/24 17:57
 * @Version 1.0
 */
public class Test9 {
    public static void main(String[] args) {
        //如完全使用配置方法去做,通过 AnnotationConfigApplicationContext上下文去获取容器,通过配置类的class对象加载
        ApplicationContext ac = new AnnotationConfigApplicationContext(UserConfig.class);
        User user = ac.getBean("getUser",User.class);
        System.out.println(user.getName());
    }
}

方式三、

注解实现自动装配
使用注解要开启注解支持

 <context:annotation-config/>
1.@Autowired  直接在属性上使用即可或者在Set方法上使用也可以。 这个注解使用反射的方式实现的,可以不写   
 SET方法也是可以注入的(前提是你要自动装配的属性在IOC容器(spring)中存在 ,符合byType)如果自动装配
 的环境比较复杂,可以添加@Qualifier(value = "dog111")去配合@Autowired,获取唯一值。@Autowired(required = 
 false)//required = false 允许在容器中为null
  
2.@Resource (是JDK的注解。不是Sping)
      
3.@Nullable
如果可以传入NULL值,则标记为@Nullable,如果不可以,则标注为@Nonnull。那么在我们做一些不安全严谨操作
的编码操作时,这些注释会给我们一些警告。


@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是
javax.annotation.Resource,但是Spring支持该注解的注入。

1、共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。

2、不同点
(1)@Autowired
    @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照
    byType注入。@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果
    允许null值,可以设置它的required属性为false.如果我们想使用按照名称(byName)来装配,可以结合@Qualifier
    注解一起使用。

(2)@Resource
    @Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两
    个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析bean
    的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策
    略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

Spring注解开发
在spring4之后要使用注解开发,必须保证导入aop架包
1.使用注解要增加注解支持!(主要是开启程序的注解驱动)

  <context:annotation-config/>
2.扫描机制
指定要扫描的包,这个包下的注解就会生效(Spring特定的注解)
<context:component-scan base-package="com"/>
注解(bean)
1.@Component(组件)
    @Component 
    等价与 
    <bean id="user" class="com.entity.User"></bean>
2.@Value()
    Spring注解注入属性值使用 @Value("大黄")
    相当于
    <property name="xxx" value="xxx"></property>
3.@Component的衍生注解
  (1)@Repository(仓库 持久层)
  (2)@Service(业务层)
  (3)@Controller(控制层)
   这四个注解的功能都是一样的,都是代表将某个类注册到Spring中,装配Bean
4.作用域的注解
    @Scope("singleton")
package com.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import javax.annotation.Resource;

/**
 * @Author Tim
 * @Date 2020/7/24 14:37
 * @Version 1.0
 */
public class Peope {
    @Resource
    private Cat cat;
    @Autowired(required = false)//required = false 允许在容器中为null
    @Qualifier(value = "dog111")
    private Dog dog;

    private String name;

    public void show(){
        cat.Show();
        dog.show();
        System.out.println("你们都是我的宠物");
    }
}
package com.bean;

/**
 * @Author Tim
 * @Date 2020/7/24 14:30
 * @Version 1.0
 */
public class Cat {
    private String name;
    public void Show(){
        System.out.println("你好我是小猫咪");
    }
}



package com.bean;

/**
 * @Author Tim
 * @Date 2020/7/24 14:36
 * @Version 1.0
 */
public class Dog {
    private String name;
    public void show(){
        System.out.println("我是一个汪星人");
    }
}


<?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">
    <bean id="cat" class="com.bean.Cat"></bean>
    <bean id="dog11" class="com.bean.Dog"></bean>
    <bean id="dog111" class="com.bean.Dog"></bean>

    <bean id="people" class="com.bean.Peope"></bean>
    <!-- 开启注解支持-->
    <context:annotation-config/>

</beans>

最后

感谢你看到这里,看完有什么的不懂的可以在评论区问我,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272