Spring IoC简单介绍以及Spring中常用注解的简单介绍

本文详细介绍了Spring框架的核心概念,包括Spring的IoC(控制反转)和DI(依赖注入)。首先从Spring入门案例出发,讲解如何创建Spring项目,配置依赖,创建和管理对象。接着深入探讨了Spring的DI,分为基于XML的DI和基于注解的DI,通过实例展示了set注入和构造注入的使用。此外,文章还提到了Spring中常用的注解,如@Component、@Autowired、@Qualifier等,以及它们在属性赋值和对象创建中的作用。
摘要由CSDN通过智能技术生成

一、Spring入门案例

Spring概念: Spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版。Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率。

Spring优点:

  • 低侵入式设计,代码的污染极低。

  • 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺。

  • Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦。

  • Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。

  • Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。

  • Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。

Spring核心技术: IoCAOP,能够实现类之间、模块之间的解耦合。

IoC: IoC(控制反转)就是依赖倒置原则的一种代码设计思路。就是把原先在代码里面需要实现的对象创建、对象之间的依赖,反转给容器来帮忙实现。
Spring IOC容器通过xml,注解等其它方式配置类及类之间的依赖关系,完成了对象的创建和依赖的管理注入。实现IOC的主要设计模式是工厂模式。

IoC技术实现: DI是IoC的技术实现, DI(Dependency Injection)依赖注入,只需要在程序中提供要使用的对象的名称就可以,至于对象在容器中如何创建、赋值、查找都由容器内部实现。Spring是使用DI实现了IoC的实现,Spring底层创建对象使用的是反射机制。

使用IoC,由Spring创建对象实现步骤:

1. 创建maven项目

在这里插入图片描述

2. 加入maven的依赖:Spring的依赖,junit依赖
<dependencies>
    <!--Spring依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    
    <!--单元测试依赖-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
3. 创建类(接口和实现类):创建类和没有使用框架一样,就是普通类。

在这里插入图片描述

4. 创建Spring需要使用的配置文件,声明类信息,这些类交由Spring创建和管理

Spring的配置文件:

  1. beans:是根标签,Spring把java对象称为bean。
  2. spring-beans.xsd:是约束文件,和mybatis指定 .dtd是一样的。

告诉Spring创建对象:
首先要声明bean,一个bean标签声明一个对象,就是告诉Spring要创建某个类的对象。
id: 对象的定义名称,唯一值。Spring就是通过这个名称找到对象。
class: 类的全限定名(不能是接口,因为Spring是反射机制创建对象,必须是类)

<bean id="someServiceImpl" class="com.cn.spring.serviceImpl.SomeServiceImpl">
</bean>
5. 测试Spring创建的对象

使用由Spring创建的对象:

  1. 指定Spring配置文件的名称
    String config="ApplicationContext.xml";

  2. 创建表示Spring容器的对象,ApplicationContext;

    • ApplicationContext就是表示Sprring容器,通过容器获取对象;
    • ClassPathXmlApplicationContext:表示从类路径中加载Spring的配置文件(在target下面读取指定配置文件,读取到声明的bean时会根据类的全限定路径找到该类然后调用该类的无参构造(spring默认调用无参构造)创建该类的对象,并将创建好的对象放到容器中);
    • Spring默认创建对象的时间:在创建spring的容器时,会创建配置文件中的所有的对象。
ApplicationContext ac=new ClassPathXmlApplicationContext(config);

从容器中获取对象:
注意:getBean(“配置文件中bean的id值”);因为getBean返回值类型是Objecct类型的所以需要强转;

SomeService ss=(SomeService) ac.getBean("someServiceImpl");

测试结果:

package com.cn.spring;

import com.cn.spring.service.SomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
	@Test
	public void test01(){
    	String config="ApplicationContext.xml";
    	ApplicationContext ac=new ClassPathXmlApplicationContext(config);
    	SomeService ss=(SomeService) ac.getBean("someServiceImpl");
    	ss.doSome();
	}
}

在这里插入图片描述


二、Spring的DI

DI:依赖注入,表示创建对象,给属性赋值。
DI的实现有两种:

  • 在Spring的配置文件中,使用标签和属性完成,叫做基于XML的DI实现。
  • 使用Spring中的注解,完成属性赋值,叫做基于注解的DI实现。

DI语法分类:

  • set注入(设值注入):spring调用set方法,在set方法可以实现属性的赋值。
  • 构造注入:spring调用类的有参构造,创建对象,在构造方法中完成赋值。
一、基于XML的DI

1.1、set注入
a、简单类型的set注入

	<bean id="XXX" class="类权限定名">
        	<!--注意:一个property只能给一个属性赋值-->
        	<property name="属性名字" value="此属性值"/>
	</bean>
b、引用类型的set注入
	<bean id="myStudent" class="类全限定名">
        <property name="引用类型属性名" ref="指向引用类型声明bean时的id值"/>
    </bean>
    <bean id="mySchool" class="类全限定名">
        <property name="tel" value="130000000"/>
    </bean>

测试结果:
在这里插入图片描述

1.2、构造注入
构造注入:spring调用类的有参构造,在创建对象的同时在构造方法中给属性赋值;

  public Student() {}//spring默认创建对象调用的是无参构造

    /**
     * 创建有参构造完成属性的赋值
     * @param name
     * @param age
     * @param school
     */
    public Student(String name, int age, School school) {
        /*给属性赋值*/
        this.name = name;
        this.age = age;
        this.school = school;
        System.out.println("----------student有参数构造方法---------");
    }

构造注入使用<constructor-arg>标签;
<constructor-arg> 标签: 一个<constructor-arg>标签表示构造方法一个参数,如果构造方法有多个参数则需要多个<constructor-arg>标签。
<constructor-arg>标签属性:
name:构造方法形参名;
index:构造方法形参位置,参数从左往右位置是0、1、2的顺序;
velue:属性值,构造方法的属性是简单类型的则使用velue;
ref:属性值,构造方法的属性是引用类型的则使用ref;

   <bean id="myStudent01" class="com.cn.spring.testDI01.testDI.Student">
        <constructor-arg value="李四"/>
        <constructor-arg value="23"/>
        <constructor-arg ref="mySchool01"/>
    </bean>
    <bean id="mySchool01" class="com.cn.spring.testDI01.testDI.School">
        <constructor-arg value="清华大学"/>
        <constructor-arg value="010-1111111"/>
    </bean>

测试结果:
在这里插入图片描述

引用类型的自动注入:
Spring根据某些规则可以给引用类型进行赋值,不用再手动给引用类型赋值了;赋值方式:byName和byType
1、byName(按名称注入): java类中引用类型和spring容器(配置文件)中bean标签的id名一致,且数据类型一致,这样spring就会给bean标签中的引用类型赋值。
语法:

<bean id="xxx" class="yyy" autowire="byName">
		简单类型属性赋值
	</bean>

配置文件配置:

    <bean id="myStudent01" class="com.cn.spring.testDI01.testDI.Student" autowire="byName">
        <property name="name" value="王五"/>
        <property name="age" value="18"/>
    </bean>
    <bean id="school" class="com.cn.spring.testDI01.testDI.School">
        <property name="name" value="理工大学"/>
        <property name="tel" value="010-7777777"/>
    </bean>

测试结果:
在这里插入图片描述

2、byType(按类型注入): java类中引用类型的数据类型和spring容器中(配置文件)bean的 class属性是同源关系,这样的bean能够赋值给引用类型。
同源关系:
a、java类中引用类型的数据类型和容器中的bean的class值是一样的;
b、java类中引用类型的数据类型和容器中的bean的class的值是父子类关系的;
c、java中引用了欸行的数据类型和容器中的bean的class的值是接口与实现类的关系的;
语法:

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

配置文件配置:

    <bean id="myStudent01" class="com.cn.spring.testDI01.testDI.Student" autowire="byType">
        <property name="name" value="赵六"/>
        <property name="age" value="18"/>
    </bean>
    <bean id="school" class="com.cn.spring.testDI01.testDI.School">
        <property name="name" value="人民大学"/>
        <property name="tel" value="010-8888888"/>
    </bean>

测试结果:
在这里插入图片描述

二、基于注解的DI:

通过注解完成java对象的创建和属性赋值;

使用注解的步骤:
1、加入maven依赖 spring-context,加入context的同时会自动加入spring-aop的依赖;使用注解必须使用spring-aop依赖。
2、在类中加入spring注解(多个不同功能的注解);
3、在spring配置文件中,加入一个组件扫描器的标签,说明注解在项目中的位置;
创建类: 类上面加上@Component注解并指定名称
@Component 创建对象的,相当于的功能
属性:value 就是对象的名称,也就是bean的id名;
value的值是唯一的,创建的对象在整个spring中只有一个;
位置:在类的上面;
创建的对象放在spring的容器中;

//使用value指定名称
//@Component(value="myStudent")
//也可以省略value
//@Component("myStudent")
//也可以不指定名称,由spring指定默认的名称(注意:默认的名称就是类名首字母小写,使用getBean的时候就写这个名称)
@Component
public class Student {
    private String name;
    private int age;

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

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

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

在配置文件中指定组件:
声明组件扫描器(component-scan),组件就是java对象,
base-package="":指定注解在项目中的包名。
component-scan工作方式:spring会扫描遍历base-package指定的包,把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象或者给属性赋值。

<context:component-scan base-package="com.spring.di.anno"/>

指定多个包的方式:
1、指定多次组件扫描器,指定不同的包;

<context:component-scan base-package="com.spring.di.anno"/>
<context:component-scan base-package="com.spring.di.anno01"/>
......

2、使用分隔符( ; 或 , )分割多个包名

<context:component-scan base-package="com.spring.di.anno;com.spring.di.anno01"/>

3、指定父包(扫描器的特点是扫描当前包以及子包中所有的类)

<context:component-scan base-package="com.spring.di"/>

创建测试类进行测试:

public class TestAnno {
    @Test
    public void testAnno(){
        String config="applictionContext.xml";
        ApplicationContext ac=new ClassPathXmlApplicationContext(config);
        Student sd= (Student) ac.getBean("myStudent");
        System.out.println(sd);
    }
}

测试结果:
在这里插入图片描述

Spring中和@Component功能一致,创建对象的注解还有:
1、@Repository(放在持久层上面的):放在dao的实现上面,表示创建dao对象,dao是访问数据库的;
2、@Service(放在业务层上面的):放在service的实现类上面,创建service对象,service对象是做业务处理,可以有事务等功能的。
3、@Controller(放在控制器上面的):放在控制器(处理器)上面,创建控制器对象,能够接受用户请求的参数,显示请求处理的结果。
以上这三个注解使用语法和@Component是一样的,但是这三个注解还有额外的功能。
@Repository、@Service、@Controller这三个注解是给项目分层用的。

简单类型的属性赋值@Value
@Value简单类型的赋值
属性:value,是String类型的,表示简单类型的属性值;
位置:1、用在属性定义的上面,无需set方法;
2、用在set方法的上面;
测试1:
在这里插入图片描述

测试2:

引用类型的属性赋值@Autowired
@Autowired:spring框架提供的注解,实现引用类型的赋值。
spring中通过注解给引用类型赋值,实现的原理是自动注入,支持byName,byType;
@Autowired:默认使用的是byType自动注入。
位置:1、引用类型定义上面(推荐使用),无需set方法;2、set方法上面(不推荐使用);
@Autowired
private School school;

测试:
在这里插入图片描述

自动注入使用byName:
@Autowired默认使用的是byType自动注入,如果要使用byName自动注入需要做如下步骤:
1、在属性上面加@Autowired注解;
2、在属性上面加@Qualifier(value=“bean的id”):表示指定名称的bean完成赋值;
注意:
在这里插入图片描述

测试:
在这里插入图片描述

@Autowired注解的required属性:

@Autowired(required = false/true)
required:是一个boolean类型的,默认为true;
required = true:表示引用类型赋值失败,并终止执行;
required = false:表示引用类型赋值失败,程序正常执行,引用类型为null
一般在项目中使用默认的true,当赋值失败的时候直接抛错可以更准确的定位到错误位置;

@Resource注解
@Resource注解来自jdk中的注解,spring框架提供了对这个注解的支持,可以使用它给引用类型赋值。
@Resource使用的也是自动注入原理,支持byName和byType,默认是byName;
位置:1、在引用类型的定义上面,无需set方法(推荐使用);2、在set方法上(不推荐使用)
@Resource在自动注入的时候默认为byName,当使用byName赋值失败的时候则自动使用byType进行赋值;
如果@Resource只是用buName则需要指定name:@Resource(name=“bean的id”)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值