spring学习笔记(二)2. Spring核心之IoC控制反转

2. Spring核心之IoC控制反转

2.1 IoC的概念

IoC—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。

IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IoC 思想。

2.2 Spring入门案例

2.2.1 创建maven项目

创建完毕的目录结构
在这里插入图片描述

2.2.2 pom.xml文件添加依赖和插件

<dependencies>
    <!--单元测试-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <!--spring依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.13.RELEASE</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

2.2.3 创建一个实体类

public class Team {
    private Integer id;
    private String name;
    private String location;

    public Team() {
        System.out.println("---team---默认的构造方法---id="+id+",name="+name+",location="+location);
    }
}

2.2.4 创建Spring的配置文件application.xml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pkpqEtz3-1628858997584)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210725121824185.png)]

2.2.5 使用Spring容器创建对象

配置文件中创建对象

<?xml version="1.0" encoding="UTF-8"?>
<!--Spring配置文件
    beans:根标签
        spring中Java的对象成为Java bean
        spring-beans.xsd是一个约束文件,约束xml文件都能编写哪些标签
-->
<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,要告知spring容器创建对象
        一个bean标签标识一个对象
        id="对象名",要求唯一值
        class="完全限定名",spring底层是通过反射方式创建对象,不能写接口
        相当于 Team team1=new Team();创建好的对象放入一个集合Map中
        例如:springMap.put("team1",new Team());
    -->
    <bean id="team1" class="com.zisen.pojo.Team"></bean>
</beans>

2.2.6 获取Spring容器

Spring 提供了两种 IoC 容器,分别为 BeanFactory 和 ApplicationContext.

2.2.6.1 BeanFactory

BeanFactory 是基础类型的 IoC 容器,是一个管理 Bean 的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。

BeanFactory 接口有多个实现类,最常见的是org.Springframework.beans.factory.xml.XmlBeanFactory,它是根据 XML 配置文件中的定义装配Bean 的。

BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource(Spring配置文件的名称));
2.2.6.2 ApplicationContext

ApplicationContext 是 BeanFactory 的子接口,也被称为应用上下文。它不仅提供了 BeanFactory 的所有功能,还添加了对 i18n(国际化)、资源访问、事件传播等方面的良好支持。

ApplicationContext 接口有两个常用的实现类:

2.2.6.2.1 ClassPathXmlApplicationContext——常用

该类从类路径 ClassPath 中寻找指定的 XML 配置文件,找到并装载完成 ApplicationContext 的实例化工作

ApplicationContext applicationContext=new ClassPathXmlApplicationContext(Spring配置文件的名称);
2.2.6.2.2 FileSystemXmlApplicationContext
ApplicationContext applicationContext = new
FileSystemXmlApplicationContext(String configLocation);

它与 ClassPathXmlApplicationContext 的区别是:在读取 Spring 的配置文件时,FileSystemXmlApplicationContext 不再从类路径中读取配置文件,而是通过参数指定配置文件的位置,它可以获取类路径之外的资源,如“D:\application.xml”。

2.2.7 获取上下文对象获取容器中的对象

package com.zisen.pojo;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TeamTest {
    @Test
    public void test01() {
        //使用spring容器创建对象
        //1、指定spring配置文件的名称
        String springConfig = "application.xml";
        //2、创建spring容器的对象:
        //方式1:不推荐,了解
        //BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("D:/workspaces/ideaProjects/MySpring/spring01/src/main/resources/application.xml"));
        //beanFactory.getBean("team1");//根据ID从IOC容器获取对象
        //方式2:applicationContext--常用
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfig);//这里执行完毕容器中的对象都已经创建完成
        // 方式3:applicationContext--了解
        //ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext("D:/workspaces/ideaProjects/MySpring/spring01/src/main/resources/application.xml");
        //3、获取容器中的对象
        Team team1 = (Team) applicationContext.getBean("team1");
        //4、容器其他api
        int beanDefinitionCount = applicationContext.getBeanDefinitionCount();
        System.out.println("spring容器中对象的个数:" + beanDefinitionCount);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        System.out.println("spring容器中所有对象的名称:");
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }
}

2.2.8 创建非自定义对象

在.xml文件中补充:

<!--创建非自定义的对象-->
<bean id="date" class="java.util.Date"></bean>

上面的测试方法中添加如下内容:

//5、获取日期对象
Date date1= (Date) applicationContext.getBean("date1");
System.out.println("日期:"+date1);

2.2.9 bean标签的属性

属性说明
class指定bean对应类的全路径
namename是bean对应对象的一个标识
scope执行bean对象创建模式和生命周期,scope="singleton"和scope=“prototype”
idid是bean对象的唯一标识,不能添加特别字符
lazy-init是否延时加载 默认值:false。true 延迟加载对象,当对象被调用的时候才会加载,测试 的时候,通过getbean()方法获得对象。lazy-init=“false” 默认值,不延迟,无论对象 是否被使用,都会立即创建对象,测试时只需要加载配置文件即可。注意:测试的时候只 留下id,class属性
init -method只需要加载配置文件即可对象初始化方法
destroy -method对象销毁方法

示例显示:

public void init(){
System.out.println("Team ---- init()");
} 
public void destroy(){
System.out.println("Team ---- destroy()");
}

application.xml配置文件添加如下内容:

<!--
	bean标签的属性:
    id="自定义的对象名称" ,要求唯一
    name="bean对于的一个标识“,一般使用id居多
    class="类的完全限定名"
    scope="singleton/prototype" 单例/多例
    	singleton:默认值,单例:在容器启动的时候就已经创建了对象,而且整个容器只有为一个的一个对象
		prototype:多例,在使用对象的时候才创建对象,每次使用都创建新的对象
	lazy-init="true/false" 是否延迟创建对象,只针对单例有效
		true:不延迟创建对象,容器加载的时候立即创建
		false:默认加载,使用对象的时候才去创建对象
	生命周期相关:
        init-method="创建对象之后执行的初始化方法"
        destroy-method="对象销毁方法,调用容器destroy方法的时候执行"
-->
<bean id="team2" class="com.kkb.pojo.Team" scope="singleton" lazyinit="true" init-method="init" destroy-method="destroy"/>
<bean id="team3" class="com.kkb.pojo.Team" scope="prototype" />

测试代码:

@Test
public void test02(){
    String springConfig="application.xml";
    ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext(springConfig);
    Team team1 = (Team) applicationContext.getBean("team1");
    Team team11 = (Team) applicationContext.getBean("team1");
    System.out.println(team1);
    System.out.println(team11);
    Team team2 = (Team) applicationContext.getBean("team2");
    Team team22 = (Team) applicationContext.getBean("team2");
    System.out.println(team2);
    System.out.println(team22);
    applicationContext.close();//关闭容器
}

2.3 Spring容器创建对象的方式

2.3.1 使用默认的构造方法

同上实例

<!--1.通过默认构造方法-->
<bean id="team1" class="com.zisen.pojo.Team"/>

2.3.2 使用带参数的构造方法

Team.java类中添加带参数的构造方法:

public Team(Integer id, String name, String location) {
    this.id = id;
    this.name = name;
    this.location = location;
    System.out.println("---team---带参数的构造方法---id="+id+",name="+name+",location="+location);
}

修改xml文件:

<!--2.通过有参数的构造方法-->
<bean id="team2" class="com.zisen.pojo.Team">
    <!--name:表示参数的名称-->
    <constructor-arg name="id" value="1001"></constructor-arg>
    <constructor-arg name="name" value="ys"></constructor-arg>
    <constructor-arg name="location" value="xx"></constructor-arg>
</bean>
<bean id="team3" class="com.zisen.pojo.Team">
    <!--index:表示参数的下标索引-->
    <constructor-arg index="0" value="1001"></constructor-arg>
    <constructor-arg index="1" value="ys"></constructor-arg>
    <constructor-arg index="2" value="xx"></constructor-arg>
</bean>

2.3.3 使用工厂类

创建工厂类:

package com.zisen.pojo;

public class MyFactory {
    /**
     * 实例方法
     * @return
     */
    public Team instanceFun(){
        return new Team(1003,"实例方法","aa");
    }

    /**
     * 静态方法
     * @return
     */
    public static Team staticFun(){
        return new Team(1004,"静态","aa");
    }
}

xml文件

<!--3.通过工厂方法
    3.1静态方法 Team team1 = MyFactory.staticFun();-->
<bean id="staticTeam" class="com.zisen.pojo.MyFactory" factory-method="staticFun">
</bean>
<!--3.通过工厂方法
    3.2实例方法
    MyFactory myFactory=new MyFactory();
    Team team = myFactory.instanceFun();-->
<bean id="factory" class="com.zisen.pojo.MyFactory"></bean>
<bean id="instanceTeam" factory-bean="factory" factory-method="instanceFun"></bean>

2.4 基于xml的DI

DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

IoC 是一个概念,是一种思想,其实现方式多种多样。依赖注入就是其中用的比较多的一种方式。

IoC和DI是同一个概念的不同角度描述。IoC是一种思想,概念,DI是实现它的手段。Spring框架使用依赖注入实现IoC。

Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。

Spring 容器管理着容器中 Bean 之间的依赖关系,Spring 使用“依赖注入”的方式来管理 Bean 之间的依赖关系。使用 IoC 实现对象之间的解耦和。

2.4.1 准备实例

创建TeamDao.java:

package com.zisen.dao;

public class TeamDao {
    public void add(){
        System.out.println("TeamDao---add()");
    }
}

创建TeamService.java:

package com.zisen.service;

import com.zisen.dao.TeamDao;

public class TeamService {
    private TeamDao teamDao;

    public void add(){
        teamDao.add();
        System.out.println("TeamService---add()");
    }

    public void setTeamDao(TeamDao teamDao) {
        this.teamDao = teamDao;
    }
}

传统做法,测试类:

@Test
public void add() {
    TeamDao dao=new TeamDao();
    TeamService service=new TeamService();
    service.setTeamDao(dao);
    service.add();
}

创建DI.xml

2.4.2 注入分类

bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。

2.4.1.1 通过set方法注入

set 注入也叫设值注入是指,通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在Spring 的依赖注入中大量使用。

DI.xml

<bean id="teamDao" class="com.zisen.dao.TeamDao"></bean>
<bean id="teamService" class="com.zisen.service.TeamService">
    <!--使用set方法注入属性值-->
    <property name="teamDao" ref="teamDao"></property>
</bean>

测试类:

@Test
public void add2() {
    ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
    TeamService teamService = (TeamService) ac.getBean("teamService");
    teamService.add();
}

**注意:**使用set注入时,必须有get/set方法。

2.4.1.2 通过构造方法

构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。使用构造器设置依赖关系。

在TeamServic.java添加带参构造方法:

public TeamService(TeamDao teamDao) {
    this.teamDao = teamDao;
}

DI.xml

<bean id="teamService2" class="com.zisen.service.TeamService">
    <!--通过构造方法-->
    <property name="teamDao" ref="teamDao"></property>
</bean>

测试类:

@Test
public void add3() {
    ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
    TeamService teamService = (TeamService) ac.getBean("teamService2");
    teamService.add();
}
2.4.1.3 自动注入

对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为标签设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属 性)。根据自动注入判断标准的不同,可以分为两种:
byName:根据名称自动注入
byType: 根据类型自动注入

1、 byName

当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用byName 方式,让容器自动将被调用者 bean 注入给调用者 bean。容器是通过调用者的 bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。

DI.xml

<!--自动注入,
        byName查询与属性值相同名称的容器中的对象,-->
    <bean id="teamService3" class="com.zisen.service.TeamService" autowire="byName">
    </bean>

测试类:

@Test
public void add4() {
    ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
    TeamService teamService = (TeamService) ac.getBean("teamService3");
    teamService.add();
}

2、 byType

使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 bean 类的某引用类型属性类型同源。即要么相同,要么有 is-a 关系(子类,或是实现类)。但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。

DI.xml

<!--自动注入,
        byType查询与属性值相同类型的容器中的对象,
        但是要求类型相同的对象唯一,否则抛出异常,不知道用哪一个-->
<bean id="teamService4" class="com.zisen.service.TeamService" autowire="byType">
</bean>

测试类:

@Test
public void add5() {
    ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
    TeamService teamService = (TeamService) ac.getBean("teamService4");
    teamService.add();
}
示例总结:

TeamDao

package com.zisen.dao;

public class TeamDao {
    public void add(){
        System.out.println("TeamDao---add()");
    }
}

TeamService

package com.zisen.service;

import com.zisen.dao.TeamDao;

public class TeamService {
    private TeamDao teamDao;

    public TeamService() {
    }

    public TeamService(TeamDao teamDao) {
        this.teamDao = teamDao;
    }

    public void add(){
        teamDao.add();
        System.out.println("TeamService---add()");
    }

    public void setTeamDao(TeamDao teamDao) {
        this.teamDao = teamDao;
    }
}

DI.xml

<?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="teamDao" class="com.zisen.dao.TeamDao"></bean>
    <bean id="teamService" class="com.zisen.service.TeamService">
        <!--使用set方法注入属性值-->
        <property name="teamDao" ref="teamDao"></property>
    </bean>

    <bean id="teamService2" class="com.zisen.service.TeamService">
        <!--通过构造方法-->
        <property name="teamDao" ref="teamDao"></property>
    </bean>

    <!--自动注入,
        byName查询与属性值相同名称的容器中的对象,-->
    <bean id="teamService3" class="com.zisen.service.TeamService" autowire="byName">
    </bean>
    <!--自动注入,
        byType查询与属性值相同类型的容器中的对象,
        但是要求类型相同的对象唯一,否则抛出异常,不知道用哪一个-->
    <bean id="teamService4" class="com.zisen.service.TeamService" autowire="byType">
    </bean>
</beans>

测试类

package com.zisen.service;

import com.zisen.dao.TeamDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TeamServiceTest {
    
    @Test
    public void add() {
        TeamDao dao=new TeamDao();
        TeamService service=new TeamService();
        service.setTeamDao(dao);
        service.add();
    }
    
    @Test
    public void add2() {
        ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
        TeamService teamService = (TeamService) ac.getBean("teamService");
        teamService.add();
    }
    
    @Test
    public void add3() {
        ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
        TeamService teamService = (TeamService) ac.getBean("teamService2");
        teamService.add();
    }

    @Test
    public void add4() {
        ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
        TeamService teamService = (TeamService) ac.getBean("teamService3");
        teamService.add();
    }

    @Test
    public void add5() {
        ApplicationContext ac=new ClassPathXmlApplicationContext("DI.xml");
        TeamService teamService = (TeamService) ac.getBean("teamService4");
        teamService.add();
    }

}

2.5 基于注解实现IoC–重要

对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。Spring 中使用注解,需要在原有Spring 运行环境基础上再做一些改变。

2.5.1 声明bean的注解@Component

在类上添加注解@Component表示该类创建对象的权限交给Spring容器。注解的value属性用于指定bean的id值,value可以省略。

@Component 不指定 value 属性,bean 的 id 是类名的首字母小写。

package com.zisen.dao;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

//@Component 注解标识在类上,表示对象由spring容器创建,value属性表示创建的id值,value可以省略,值也可以省略,默认就是类名首字母小写
//<bean id="teamDao" class="com.zisen.dao.TeamDao"></bean>
@Component
//@Repository
public class TeamDao {
    public void add(){
        System.out.println("TeamDao---add()");
    }

    public TeamDao() {
        System.out.println("TeamDao---默认构造方法");
    }
}

除此之外,Spring中还提供了其他3个用于创建对象的注解:

@Repository : 用于dao实现类的的注解

@Service: 用户service实现类的注解

@Controller: 用于controller实现类的注解

这三个注解与@Component 都可以创建对象,但这三个注解还有其他的含义,@Service创建业务层对象,业务层对象可以加入事务功能,@Controller 注解创建的对象可以作为处理器接收用户的请求。

@Repository,@Service,@Controller 是对@Component 注解的细化,标注不同层的对象。即持久层对象,业务层对象,控制层对象。

2.5.2 包扫描

需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。如果没有报扫描,添加的创建对象的注解不生效。

注意:在beans标签中添加命名空间:xmlns:context="http://www.springframework.org/schema/context"
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

如果要扫描的包有多个,可以有以下方式扫描:

1、使用多个context:component-scan指定不同的包路径

<?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 http://www.springframework.org/schema/context/spring-context.xsd">

    <!--表示告知spring要扫描的包
    这些包以及子包当中的类上添加了@component注解,这些添加了注解类交给了spring容器创建对象
    注意:在beans标签中添加命名空间:xmlns:context="http://www.springframework.org/schema/context"
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    -->
    <!--多个包的扫描:
    方式1:使用多个<context:component-scan base-package="com.zisen.dao"></context:component-scan>-->
    <context:component-scan base-package="com.zisen.dao"></context:component-scan>
    <context:component-scan base-package="com.zisen.service"></context:component-scan>
    <context:component-scan base-package="com.zisen.controller"></context:component-scan>
    <!--方式2:在base-package直接声明要扫描的多个包,中间用“,”或者“;”分开-->
    <!--<context:component-scan base-package="com.zisen.dao,com.zisen.service,com.zisen.controller"></context:component-scan>-->

    <!--方式3:在base-package直接声明要扫描的多个包的父包-->
    <!--<context:component-scan base-package="com.zisen"></context:component-scan>
-->
</beans>

2、指定 base-package的值使用分隔符

分隔符可以使用逗号(,)分号(;)还可以使用空格,不建议使用空格。

<!--方式2:在base-package直接声明要扫描的多个包,中间用“,”或者“;”分开-->
<context:component-scan base-package="com.zisen.dao,com.zisen.service,com.zisen.controller"></context:component-scan>

3、base-package是指定到父包名

base-package 的值表是基本包,容器启动会扫描包及其子包中的注解,当然也会扫描到子包下级的子包。所以 base-package 可以指定一个父包就可以。

但不建议使用顶级的父包,扫描的路径比较多,导致容器启动时间变慢。指定到目标包和合适的。也就是注解所在包全路径

<!--方式3:在base-package直接声明要扫描的多个包的父包-->
<context:component-scan base-package="com.zisen"></context:component-scan>

2.5.3 属性注入@Value

需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。
在这里插入图片描述

2.5.4 byType自动注入@Autowired

需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。

2.5.5 byName自动注入@Autowired和@Qualifier

需要在引用属性上联合使用注解@Autowired 与@Qualifier。@Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值。类中无需 set 方法,也可加到 set 方法上。

@Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。

在这里插入图片描述

2.5.6 自动注入@Resource

Spring提供了对 jdk中@Resource注解的支持。@Resource 注解既可以按名称匹配Bean,也可以按类型匹配 Bean。默认是按名称注入。使用该注解,要求 JDK 必须是 6 及以上版本。@Resource 可在属性上,也可在 set 方法上。

1、byType注入引用类型属性

@Resource 注解若不带任何参数,采用默认按名称的方式注入,按名称不能注入 bean,则会按照类型进行 Bean 的匹配注入。

2、byName注入引用类型属性

@Resource 注解指定其 name 属性,则 name 的值即为按照名称进行匹配的 Bean 的 id。

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值