Spring框架-----2

本文详细介绍了Spring框架中的依赖注入(DI)概念、方式(构造方法与set方法)、适用场景,涵盖不同类型的数据注入,自动注入和注解使用,以及分层设计。通过实例解析了Spring IOC和DI创建对象的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.依赖注入DI (就是给对象中的属性赋值:构造赋值,set方法赋值)

1.1.概念

1.2.注入的方式

1.通过set方法注入。用的非常多。

2.通过构造方法。class类不是你定义,而是使用别人的类,而别人写的类没有无参构造函数。  

1.3.什么时候使用IOC和DI创建对象?

2. 依赖注入的类型有哪些?

3. 如何实现注入对象的属性值

4. 使用spring注入其他数据类型

4.1 注入类对象类型

4.2 注入集合类型和数组

4.3 注入set和map集合

5. 自动注入

6. 使用注解完成IOC和DI功能(注意开启注解的包扫描)

7.分层

8.注解分类


1.依赖注入DI (就是给对象中的属性赋值:构造赋值,set方法赋值)

1.1.概念

IOC控制反转的最终目的就是降低程序的耦合,也就是削减依赖关系。

依赖关系的管理以后都交给spring维护,依赖关系的管理就称之为依赖注入。也就是说在当前类需要用到其它类的对象时,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护就可以了。

  • 依赖注入(Dependency Injection,DI)。

  • 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .

  • 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .

IOC:控制反转 创建对象!

DI 依赖注入:目的就是给对象中的属性赋值。

1.2.注入的方式

1.通过set方法注入。用的非常多。

如果使用set函数注入,需要在bean.xml文件的bean标签中添加 property 标签

​ 需要属性:

​ name: 用于给无参空构造函数的参数赋值,指定设值的set方法(将set方法的set去掉把大写字母变小写 setAge()====>age)

​ value : 用于提供基本类型和String类型的数据

​ ref : 用于指定其它的bean类型数据,它指的就是在spring的IOC核心容器中出现过的bean

优点:解决了构造注入时的问题,可以选择性的注入值,不是必须注入全部了。

  <bean id="userService" class="com.wzh.service.UserService">
        <!--property:为类中属性赋值通过set方法赋值。name:表示属性名.
                        ref:值的引用
        -->
        <property name="userDao" ref="mysql"/>
    </bean>

2.通过构造方法。class类不是你定义,而是使用别人的类,而别人写的类没有无参构造函数。  

<bean id="userService" class="com.wzh.service.UserService">
          <!--通过构造方法为类中属性注入:参数的下标-->
<!--          <constructor-arg index="0" ref="oracle"/>-->
        <!--通过构造方法为类中属性注入:参数名称-->
<!--         <constructor-arg name="userDao" ref="mysql"/>-->
         <constructor-arg type="com.ykq.dao.UserDao" ref="mysql"/>
    </bean>

argument

​ 如果使用构造函数注入,需要在bean.xml文件的bean标签中添加constructor-arg标签

​ 标签中的属性:

​ type : 用于指定要注入的数据的类型,该数据类型也是构造函数中某个或某些参数的类型。

​ index: 用指定给构造函数中指定索引位置的参数赋值,索引从0开始。

​ name: 用于给构造函数的参数赋值,指定参数的名称直接赋值 (常用)

​ value : 用于提供基本类型和String类型的数据

​ ref : 用于指定其它的bean类型数据,它指的就是在spring的IOC核心容器中出现过的bean

注意:在获取bean对象时,必须要注入数据,否则对象无法创建成功。

缺点:改变了bean对象的实例化方式,就算我们在创建对象时,用不到这些数据,也必须提供。

 <!--构造注入-->
    <bean id="p1" class="com.bai.demo2.entity.Person">
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="date" ref="d1"></constructor-arg>
    </bean>

    <!--日期对象的bean-->
    <bean id="d1" class="java.util.Date"></bean>

1.3.什么时候使用IOC和DI创建对象?

​ 如果是单例对象,可以使用IOC和DI。整个程序运行期间只会创建一个对象,我们不用考虑对象中数据的改变。

​ 但是,如果我们要创建的对象中的属性值,一直在改变,此时就不推荐使用DI和IOC了。

2. 依赖注入的类型有哪些?

(1)基本数据类型或者字符串。

(2)引用类型--对象类型。

(3)集合List,Set。

(4)map集合。

(5)数组

3. 如何实现注入对象的属性值

(1)创建一个类:---提供set方法

如果是基本类型和字符串类型注入值时 使用value

package com.wzh.demo;

/**
 * @ProjectName: spring0613_2
 * @Package: com.wzh.demo
 * @ClassName: Student
 * @Author: 王振华
 * @Description:
 * @Date: 2022/6/13 18:59
 * @Version: 1.0
 */
public class Student {
    private Integer age;
    private String name;

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

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

(2)配置文件:---在bean标签中<property name="属性名" >

<?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容器会帮你创建该bean的对象-->
    <bean id="student01" class="com.wzh.demo.Student">
        <!--
            property:表示为类中属性注入值,调用的为set方法
            name:表示属性名
            value:注入基本类型和字符串类型时使用value
        -->
        <property name="name" value="张三"/>
        <property name="age" value="18"/>
    </bean>
</beans>

(3)测试

import com.wzh.demo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ProjectName: spring0613_2
 * @Package: PACKAGE_NAME
 * @ClassName: Test01
 * @Author: 王振华
 * @Description:
 * @Date: 2022/6/13 19:03
 * @Version: 1.0
 */
public class Test01 {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
        Student student = (Student) app.getBean("student01");
        String s = student.toString();
        System.out.println(s);

    }
}

4. 使用spring注入其他数据类型

4.1 注入类对象类型

如果属性类型为对象类型。用ref,

4.2 注入集合类型和数组

注入list集合:

属性类型为list类型 <list></list>

 测试:

注入数组:用<array></array>

 

4.3 注入set和map集合

 map属性类型:用<map></map>

set属性类型:用<set></set>

5. 自动注入

public class UserController {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void fun(){
        userDao.show();
    }
}
public interface UserDao {

    public void show();
}

public class UserDao01 implements UserDao {
    public void show() {
        System.out.println("userDao01-------------------show方法");
    }
}




public class UserDao02 implements UserDao{
    public void show() {
        System.out.println("userDao02**************************show方法");
    }
}
autowire:自动注入属性值
no:不设置自动注入  默认值
byName:按照属性名称自动注入属性值
byType:按照属性的类型自动注入

 

 如果用byName 需要bean的id与userController的属性名一致,如:

byType会自动调用与UserController属性名类型一致的bean,如果没有或者有多个会报错

 

6. 使用注解完成IOC和DI功能(注意开启注解的包扫描)

(1)包扫描配置文件

    <!--包扫描-->
    <context:component-scan base-package="com.wzh.demo03"/>

(2)创建controller

package com.wzh.zuo.controller;

import com.wzh.zuo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;

/**
 * @ProjectName: spring0613_1
 * @Package: com.wzh.zuo.controller
 * @ClassName: UserController
 * @Author: 王振华
 * @Description:
 * @Date: 2022/6/13 17:35
 * @Version: 1.0
 */
//表示控制层注解,如何没有设置bean的id 默认为类的名称首字母小写
// 相当于在spring配置文件钟<bean id="userController"  class="com.wzh.zuo.controller"/>
@Controller(value = "userController")
public class UserController {
    @Autowired  //按照类型自动注入 如果需要自己指定名称注入需要使用另一个注解配合使用
    @Qualifier(value = "userService")
    private UserService userService;
    public void fun(){
        userService.print();
    }

}

(3) dao接口和实现类

@Repository
public class UserDaoImpl01 implements UserDao {


    public void print() {
        System.out.println("userDao01~~~~~~~~~~~~~~~~~~~~~~~~~~~~~print方法");
    }
}



@Repository
public class UserDaoImpl02 implements UserDao {


    public void print() {
        System.out.println("userDao02~~~~~~~~~~~~~~~~~~~~~~~~~~~~~print方法");
    }
}

@Controller+@Respository+@Service+@Component
没有区别: 他们的底层都是用的@Component
实际意思就在于区分层的。
@Controller控制层
@Respository持久化层
@Service 业务层
@Component 最底层的bean注解。

常见错误:

 在Controller需要注入userDao接口对象,但是在spring容器中没有创建UserDao对象的实现类对象。

(1)实现类没有注解@Respository

(2)spring配置文件中没有包扫描或者没有扫描到

7.分层

MVC开发模式,

8.注解分类

1.用于创建对象的:

​ 作用和在xml配置文件中编写一个< bean>标签实现的功能一样

@Component:(只要不属于三层架构 就使用)
    作用:用于把当前类对象存入spring容器中。
    具有value属性,用于指定bean的id,如果不写value,默认跟当前类名对应(首字母改小写)
    @Component("student1")作用就相当于:
    <bean id="id" class="全类名"></bean>
    
衍生三个注解:
@Controller(表现层)     @Service(业务层)      @Repository(持久层)
    这三个注解的作用和@Component注解一样,是spring框架为我们提供的明确的三层架构使用的注解,让我们的三层架构更加清晰。

@Controller:注解 一般作为controller
@Service: 注解 一般作为service层
@Repository:注解 一般作为dao层
@Component: 注解 如果你的类不属于上面三层,而你希望该类有spring容器来管理该类的创建。
上面这些注解都在加载类上。 作用把该类交于spring容器来创建类对象。
@Autowired: 自动注入。按照类型注入,如果有多个匹配类型,则按照名称注入。

2.用于注入数据的

​ 作用和xml文件中bean标签中的property标签的作用一样

 

@Autowired *****重点
作用:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。
    如果IOC容器中没有任何bean的类型和要注入的变量类型匹配,则报错
    如果IOC容器中有多个类型匹配时,会根据要注入的变量名作为id去匹配,如果匹配到了,就可以执行,否则,报错。
注意:使用注解时,set方法就不是必要的了。
以上@Autowired注解存在一定的局限性,(如果核心容器中有多个相同对象,只使用@Autowired是无法注入成功的)如何解决问题?

@Qualifier
    作用:在按照类型注入的基础上再按照名称注入。它再给类成员注入时不能单独使用。但是再给方法注入时可以。
    属性:value 用于指定注入的bean的id

@Resource
    作用:直接按照bean的id注入。它可以独立使用。
    属性:name   用于指定bean的id
以上三个注解都只能注入其它bean类型的数据,而基本类型和String类型无法使用上述注解。那么如何注入基本数据类型和String类型呢?(集合类型只能通过xml注入)

@Value
    作用:用于注入基本数据类型和String数据类型。

3.用于改变作用范围的

​ 作用和bean标签中的scope属性的功能一样

 @Scope:
    作用:用于指定bean的作用范围
    属性:value  指定范围的取值。常用  singleton  prototype

4.和生命周期相关的

​ 作用和bean标签中的init-method和destory-method方法的作用一样

@PostConstruct:用于指定初始化方法
@PreDestroy      :用于指定销毁方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值