Spring核心之IoC控制反转详细解释----从入门到精通

目录

 

1、IoC概念

2、入门案例

2.1、创建maven项目

2.2、pom.xml文件添加依赖和插件

2.3、创建一个实体类

2.4、创建Spring的配置文件application.xml

2.5、 获取Spring容器

2.5.1、BeanFactory

2.5.2、ApplicationContext

2.6、bean标签的属性

2.7、spring容器创建对象的三种方式

2.7.1、通过默认构造方法

2.7.2、通过带参数的构造方法

2.7.3、使用工厂类方法

2.8、 基于XML的DI

2.8.1、通过set方法

2.8.2、 通过构造方法

2.8.3、 自动注入

2.9、基于注解实现IoC--重要

2.9.1、 声明Bean的注解 @Component

2.9.2、包扫描

2.9.3、 属性注入@Vaule

2.9.4、byType自动注入@Autowired

2.9.4、byName自动注入@Autowired和@Qualifier

2.9.5、自动注入@Resource


1、IoC概念

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

IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IoC 思想。(简单的说,我们之前创建对象或者实例,都是通过构造方法new一个出来,或者通过反射、克隆,序列化,动态代理等创建,而我们学习了Spring之后,创建对象都由Spring容器创建,不再通过调用来进行管理,也就是调用者的控制权将由Spring容器来进行控制,这也就是我们所说的IoC思想)。

2、入门案例

2.1、创建maven项目

这个比较简单,小白就不再这里演示了

创建完毕的目录结构

2.2、pom.xml文件添加依赖和插件

pom.xml文件内容如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.kkb</groupId>
    <artifactId>spring01</artifactId>
    <version>1.0-SNAPSHOT</version>

    <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.6.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>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2.3、创建一个实体类

在java包下创建一个实体类,包名为com.kkb.pojo

实体类代码如下:

package com.kkb.pojo;

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.4、创建Spring的配置文件application.xml

配置文件application.xml内容,并且将一些解释也写到了里面

<?xml version="1.0" encoding="UTF-8"?>
<!--spring的配置文件
    1、beans:根标签,spring中java的对象成为bean
    2、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.kkb.pojo.Team"></bean>

</beans>

2.5、 获取Spring容器

在Spring中提供了两种IoC容器,分别是BeanFactoryApplicationContext

2.5.1、BeanFactory

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

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

用法:

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

我们用代码来演示一遍:

先创建一个Test测试类:

在学IoC之前,我们运行实体类Team里面的方法时,一般先创建新的对象,我们来测试一下:

package com.kkb;

import com.kkb.pojo.Team;


public class Test {
    @org.junit.Test
    public void test1() {
        //在学IoC之前,我们运行实体类Team里面的方法时,一般先创建新的对象,如下:
        Team team = new Team();
    }
}

运行结果如下:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=50589:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 com.kkb.Test,test1
Team的默认构造方法被调用:id=null,name=null, location=null

Process finished with exit code 0

 

接下来我们用BeanFanctory容器来测试一下:

package com.kkb;

import com.kkb.pojo.Team;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;


public class Test {
    @org.junit.Test
    public void test1() {
        //在学IoC之前,我们运行实体类Team里面的方法时,一般是程序员自己创建对象,如下:
        //Team team = new Team();

        //spring容器创建对象的方式
        String springConfig = "application.xml";//application.xml为resources包下的xml文件
        //获取Spring容器
        BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("E:/java IDEA/MySpring/spring01/src/main/resources/application.xml"));
        beanFactory.getBean("team1");//根据id从ioc容器中获取对象
    }
}

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=50708:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test,test1
Team的默认构造方法被调用:id=null,name=null, location=null

Process finished with exit code 0

2.5.2、ApplicationContext

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

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

1、ClassPathXmlApplicationContext——常用

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

用法:

ApplicationContext  applicationContex = new  ClassPathXmlApplicationContext(Spring配置文件的名称);

我们来测试一下:

package com.kkb;

import com.kkb.pojo.Team;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;

/**
 * @Author: ZhangPengCheng
 * @Date: 2021/4/18 20:35
 * @Version 1.0
 */
public class Test {
    @org.junit.Test
    public void test1() {
        //在学IoC之前,我们运行实体类Team里面的方法时,一般是程序员自己创建对象,如下:
        //Team team = new Team();

        //spring容器创建对象的方式
        String springConfig = "application.xml";//application.xml为resources包下的xml文件
        //获取Spring容器
        //方式1:
        //BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("E:/java IDEA/MySpring/spring01/src/main/resources/application.xml"));
        //beanFactory.getBean("team1");//根据id从ioc容器中获取对象
        //方式2:
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfig);
    }
}

 运行结果

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=50841:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test,test1
Team的默认构造方法被调用:id=null,name=null, location=null

Process finished with exit code 0

2、FileSystemXmlApplicationContext

用法:

ApplicationContext  applicationContext  =  new  FileSystemXmlApplicationContext(String configLocation);

我们来测试一下:

package com.kkb;

import com.kkb.pojo.Team;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;


public class Test {
    @org.junit.Test
    public void test1() {
        //在学IoC之前,我们运行实体类Team里面的方法时,一般是程序员自己创建对象,如下:
        //Team team = new Team();

        //spring容器创建对象的方式
        String springConfig = "application.xml";//application.xml为resources包下的xml文件
        //获取Spring容器
        //方式1:
        //BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("E:/java IDEA/MySpring/spring01/src/main/resources/application.xml"));
        //beanFactory.getBean("team1");//根据id从ioc容器中获取对象
        //方式2-推荐-常用:
        //ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfig);
        //方式3:
        ApplicationContext applicationContext = new FileSystemXmlApplicationContext("E:/java IDEA/MySpring/spring01/src/main/resources/application.xml");
    }
}

运行结果

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=50907:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test,test1
Team的默认构造方法被调用:id=null,name=null, location=null

Process finished with exit code 0

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

2.6、bean标签的属性

id: id是bean对象的唯一标识,不能添加特别字符

class: 指定bean对应类的全路径

name: name是bean对应对象的一个标识(一般用id比较多)

scope: 执行bean对象创建模式和生命周期,scope="singleton/prototype" 单例/多例,

            singleton:默认值,单例:在容器启动的时候就已经创建了对象,而且整个容器只有为一个的一个对象

            prototype:多例,在使用对象的时候才创建对象,每次使用都创建新的对象

lazy-init: lazy-init="true/false" 是否延迟创建对象,只针对单例有效

              true:不延迟创建对象,容器加载的时候立即创建

              false:默认加载,使用对象的时候才去创建对象

init-method: init-method="创建对象之后执行的初始化方法"

destroy-method: destroy-method="对象销毁方法,调用容器destroy方法的时候执行"

2.7、spring容器创建对象的三种方式

2.7.1、通过默认构造方法

在之前的案例中小白给大家进行演示过了,但为了更好的理解,小白给大家重新创建一个新的配置文件createType.xml进行演示

先看一下createType.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">

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

我们在创建一个新的测试类来进行测试

package com.kkb;

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


public class Test2 {
    @Test
    public void test(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("createType.xml");

    }
}

运行结果

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=59992:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test2,test
spring容器创建对象的方式1:通过默认的构造方法
Team的默认构造方法被调用:id=null,name=null, location=null

Process finished with exit code 0

2.7.2、通过带参数的构造方法

我们先在实体类Team中创建一个多参构造函数

public Team(Integer id, String name, String location) {
        this.id = id;
        this.name = name;
        this.location = location;
        System.out.println("spring容器创建对象的方式2:通过带参的构造方法");
        System.out.println("id="+id+",name="+name+", location="+location);
    }

然后我们看一下配置文件

<?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">

    <!--1、通过默认的构造方法-->
    <bean id="team1" class="com.kkb.pojo.Team"></bean>
    <!--2、通过带参数的构造方法-->
    <bean id="team2" class="com.kkb.pojo.Team">
        <!--name表示参数的名称-->
        <constructor-arg name="id" value="1001"></constructor-arg>
        <constructor-arg name="name" value="勇士"></constructor-arg>
        <constructor-arg name="location" value="金州"></constructor-arg>
    </bean>
    <!--除了用name:参数的名称来创建,我们还可以用index下标来创建-->
    <bean id="team3" class="com.kkb.pojo.Team">
        <constructor-arg index="0" value="1002"></constructor-arg>
        <constructor-arg index="1" value="热火"></constructor-arg>
        <constructor-arg index="2" value="迈阿密"></constructor-arg>
    </bean>
</beans>

运行测试类,并获取结果

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=60145:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test2,test
spring容器创建对象的方式1:通过默认的构造方法
Team的默认构造方法被调用:id=null,name=null, location=null
spring容器创建对象的方式2:通过带参的构造方法
id=1001,name=勇士, location=金州
spring容器创建对象的方式2:通过带参的构造方法
id=1002,name=热火, location=迈阿密

Process finished with exit code 0

2.7.3、使用工厂类方法

使用工厂类的方法有两种,一种是实例方法,一种是静态方法

我们先在pojo包下创建一个工厂类

package com.kkb.pojo;

/**
 * @Author: ZhangPengCheng
 * @Date: 2021/4/19 10:06
 * @Version 1.0
 */
public class MyFactory {

    /**
     *实例方法
     * @return
     */
    public Team instanceFun(){
        System.out.println("实例方法");
        return new Team(1004,"湖人","洛杉矶");
    }

    /**
     * 静态方法
     * @return
     */
    public static Team staticFun(){
        System.out.println("静态方法");
        return new Team(1005,"小牛","阿达斯");
    }
}

然后我们看一下配置文件

<?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">

    <!--1、通过默认的构造方法-->
    <bean id="team1" class="com.kkb.pojo.Team"></bean>
    <!--2、通过带参数的构造方法-->
    <bean id="team2" class="com.kkb.pojo.Team">
        <!--name表示参数的名称-->
        <constructor-arg name="id" value="1001"></constructor-arg>
        <constructor-arg name="name" value="勇士"></constructor-arg>
        <constructor-arg name="location" value="金州"></constructor-arg>
    </bean>
    <!--除了用name:参数的名称来创建,我们还可以用index下标来创建-->
    <bean id="team3" class="com.kkb.pojo.Team">
        <constructor-arg index="0" value="1002"></constructor-arg>
        <constructor-arg index="1" value="热火"></constructor-arg>
        <constructor-arg index="2" value="迈阿密"></constructor-arg>
    </bean>
    <!-- 3、通过工厂方法:实例方法,静态方法-->
    <!--静态方法-->
    <bean id="staticTeam" class="com.kkb.pojo.MyFactory" factory-method="staticFun"></bean>
    <!--实例方法-->
    <bean id="factory" class="com.kkb.pojo.MyFactory"></bean>
    <bean id="instanceTeam" factory-bean="factory" factory-method="instanceFun"></bean>
</beans>

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=60276:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test2,test
spring容器创建对象的方式1:通过默认的构造方法
Team的默认构造方法被调用:id=null,name=null, location=null
spring容器创建对象的方式2:通过带参的构造方法
id=1001,name=勇士, location=金州
spring容器创建对象的方式2:通过带参的构造方法
id=1002,name=热火, location=迈阿密
静态方法
spring容器创建对象的方式2:通过带参的构造方法
id=1005,name=小牛, location=阿达斯
实例方法
spring容器创建对象的方式2:通过带参的构造方法
id=1004,name=湖人, location=洛杉矶

Process finished with exit code 0

2.8、 基于XML的DI

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

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

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

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

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

那么注入有哪些分类呢?小白带大家一一介绍

2.8.1、通过set方法

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

我们用案例来解释一下

首先我们先创建dao层和service层

目录结构为:

TeamDao代码为:

package com.kkb.dao;


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

TeamService代码为:

package com.kkb.service;

import com.kkb.dao.TeamDao;

public class TeamService {
    private TeamDao teamDao; //注意我们这里不是 TeamDao teamDao = new TeamDao()
    public void add(){
        teamDao.add();
        System.out.println("TeamService----add----");
    }

}

我们都知道是service调用dao,但现在我们用测试类来测试一下会不会报错

测试类:

package com.kkb;

import com.kkb.service.TeamService;
import org.junit.Test;

/**
 * @Author: ZhangPengCheng
 * @Date: 2021/4/19 11:26
 * @Version 1.0
 */
public class Test3 {
    @Test
    public void test(){
        TeamService service = new TeamService();
        service.add();
    }
}

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=61170:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test3,test

java.lang.NullPointerException
	at com.kkb.service.TeamService.add(TeamService.java:14)
	at com.kkb.Test3.test(Test3.java:16)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)


Process finished with exit code -1

显示报空指针异常,学习IoC之前我们都是这样解决的,在TeamService类中创建get,set方法,如下:

package com.kkb.service;

import com.kkb.dao.TeamDao;


public class TeamService {
    private TeamDao teamDao;

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

    public TeamDao getTeamDao() {
        return teamDao;
    }

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

在看测试类:

package com.kkb;

import com.kkb.dao.TeamDao;
import com.kkb.service.TeamService;
import org.junit.Test;

/**
 * @Author: ZhangPengCheng
 * @Date: 2021/4/19 11:26
 * @Version 1.0
 */
public class Test3 {
    @Test
    public void test(){
        TeamDao teamDao = new TeamDao();
        TeamService service = new TeamService();
        service.setTeamDao(teamDao);
        service.add();
    }
}

我们再看一下运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=61224:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test3,test
TeamDao---- add----
TeamService----add----

Process finished with exit code 0

这些都是我们之前学的,但是我们怎么通过set方法来实现依赖注入呢?小白领大家来操作一番

第一步,创建配置文件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.kkb.dao.TeamDao"></bean>
    <bean id="teamService" class="com.kkb.service.TeamService">
        <!--使用set方法注入属性值-->
        <property name="teamDao" ref="teamDao"></property>
    </bean>
</beans>

测试方法:

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

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=61311:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test3,test2
TeamDao---- add----
TeamService----add----

Process finished with exit code 

我们看到运行成功,这就是通过ser方法来实现依赖注入,这也是我们比较常用的注入方法

2.8.2、 通过构造方法

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

首先在TeamService类添加构造方法

    public TeamService() {
    }

    public TeamService(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.kkb.dao.TeamDao"></bean>
    <bean id="teamService" class="com.kkb.service.TeamService">
        <!--使用set方法注入属性值-->
        <property name="teamDao" ref="teamDao"></property>
    </bean>
    
    <bean id="teamService1" class="com.kkb.service.TeamService">
        <!--使用构造方法注入属性值-->
        <constructor-arg name="teamDao" ref="teamDao"></constructor-arg>
    </bean>
</beans>

测试类:


    @Test
    public void test2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("DI.xml");
        System.out.println("通过set方法");
        TeamService teamService = (TeamService) applicationContext.getBean("teamService");
        teamService.add();
        System.out.println("通过构造方法");
        TeamService teamService1 = (TeamService) applicationContext.getBean("teamService1");
        teamService1.add();
    }

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=61417:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test3,test2
通过set方法
TeamDao---- add----
TeamService----add----
通过构造方法
TeamDao---- add----
TeamService----add----

Process finished with exit code 0

2.8.3、 自动注入

对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为标签

设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属 性)。根据自动注入判断标准的不同,可以分为两种:

byName:根据名称自动注入

byType: 根据类型自动注入

1、 byName

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

2、 byType

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

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

    <bean id="teamService1" class="com.kkb.service.TeamService">
        <!--使用构造方法注入属性值-->
        <constructor-arg name="teamDao" ref="teamDao"></constructor-arg>
    </bean>

    <!--按名称自动注入:查找容器中id名与属性名一致的对象进行注入-->
    <bean id="teamService2" class="com.kkb.service.TeamService" autowire="byName"></bean>

    <!--按类型自动注入:查找容器中类型与属性类型相同或者符合is-a关系的对象进行注入,但是要求类型相同的对象唯一,否则抛出异常:不知道用哪一个匹配-->
    <bean id="teamService3" class="com.kkb.service.TeamService" autowire="byType"></bean>
</beans>

测试类

@Test
    public void test2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("DI.xml");
        System.out.println("通过set方法");
        TeamService teamService = (TeamService) applicationContext.getBean("teamService");
        teamService.add();
        System.out.println("通过构造方法");
        TeamService teamService1 = (TeamService) applicationContext.getBean("teamService1");
        teamService1.add();
        System.out.println("按名称自动注入");
        TeamService teamService2 = (TeamService) applicationContext.getBean("teamService2");
        teamService2.add();
        System.out.println("按类型自动注入");
        TeamService teamService3 = (TeamService) applicationContext.getBean("teamService3");
        teamService3.add();
    }

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=61523:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test3,test2
通过set方法
TeamDao---- add----
TeamService----add----
通过构造方法
TeamDao---- add----
TeamService----add----
按名称自动注入
TeamDao---- add----
TeamService----add----
按类型自动注入
TeamDao---- add----
TeamService----add----

Process finished with exit code 0

2.9、基于注解实现IoC--重要

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

2.9.1、 声明Bean的注解 @Component

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

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

例如:

package com.kkb.dao;

import org.springframework.stereotype.Component;


//@Component注解标识在类上,表示对象由Spring容器创建 value属性表示创建的ID值,value可以省略,值也可以省略,默认就是类名小字母小写
@Component(value = "teamDao")
//相当于xml文件中的<bean id="teamDao" class="com.kkb.dao.TeamDao"></bean>
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 注解的细化,标注不同层的对象。即持久层对象,业务层对象,控制层对象。

所有以后在dao层声明注解我们用@Repository

如下:

package com.kkb.dao;

import org.springframework.stereotype.Repository;


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

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

在service层声明注解我们用@Service

如下:

package com.kkb.service;

import com.kkb.dao.TeamDao;
import org.springframework.stereotype.Service;


@Service
public class TeamService {
    private TeamDao teamDao;

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

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

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

    public TeamDao getTeamDao() {
        return teamDao;
    }

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

在controller层声明注解我们用@Controller

如下:

package com.kkb.controller;

import org.springframework.stereotype.Controller;

@Controller
public class TeamController {
    
    public TeamController() {
        System.out.println("TeamController-------默认的构造方法");
    }
}

2.9.2、包扫描

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

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

我们要想使用注解必须先进行包扫描,否则注解不生效,所以小白带大家进行一下包扫描。

首先我们先创建一个新的配置文件annotation.xml

然后我们要在beans标签中添加

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

如下:

<?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">


</beans>

基于以上操作,然后我们进行包扫描

1、 扫描多个包:方式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">

    <!--<context:component-scan 表示告知Spring要扫描的包
    这些包以及子包当中的类如果添加了@Component注解,这些添加注解的类就交给了Spring容器创建对象-->
    <!--使用多个context:component-scan指定不同的包路径-->
    <context:component-scan base-package="com.kkb.dao"></context:component-scan>
    <context:component-scan base-package="com.kkb.service"></context:component-scan>
    <context:component-scan base-package="com.kkb.controller"></context:component-scan>

</beans>

我们来看看dao、service、controller层能不能通过注解实现里面的默认构造方法

我们先创建一个测试类

如下:

package com.kkb;

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


public class Test4 {
    @Test
    public void test(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation.xml");
    }
}

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=62200:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test4,test
TeamDao------默认的构造方法
TeamService------默认的构造方法
TeamController-------默认的构造方法

Process finished with exit code 0

运行成功,可以通过注解来实现

2、扫描多个包:方式2、指定 base-package的值使用分隔符

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

<?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">

    <!--<context:component-scan 表示告知Spring要扫描的包
    这些包以及子包当中的类如果添加了@Component注解,这些添加注解的类就交给了Spring容器创建对象-->
    <!--扫描多个包:方式1:使用多个context:component-scan指定不同的包路径-->
    <!--<context:component-scan base-package="com.kkb.dao"></context:component-scan>
    <context:component-scan base-package="com.kkb.service"></context:component-scan>
    <context:component-scan base-package="com.kkb.controller"></context:component-scan>-->

    <!--多个包的扫描: 方式2 : base-package中直接声明要扫描的多个包 ,多个值用逗号,分号或者空格分割,但是空格不推荐-->
    <context:component-scan base-package="com.kkb.controller,com.kkb.service,com.kkb.dao"></context:component-scan>

</beans>

运行结果和方式1一样,小白就打印出来了

3、扫描多个包:方式3、base-package是指定到父包名

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

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

<?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">

    <!--<context:component-scan 表示告知Spring要扫描的包
    这些包以及子包当中的类如果添加了@Component注解,这些添加注解的类就交给了Spring容器创建对象-->
    <!--扫描多个包:方式1:使用多个context:component-scan指定不同的包路径-->
    <!--<context:component-scan base-package="com.kkb.dao"></context:component-scan>
    <context:component-scan base-package="com.kkb.service"></context:component-scan>
    <context:component-scan base-package="com.kkb.controller"></context:component-scan>-->

    <!--多个包的扫描: 方式2 : base-package中直接声明要扫描的多个包 ,多个值用逗号,分号或者空格分割,但是空格不推荐-->
    <!--<context:component-scan base-package="com.kkb.controller,com.kkb.service,com.kkb.dao"></context:component-scan>-->

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

运行结果也同方式1、2一样。

所以包扫描的三种方式小白给大家总结完了,记住:要想让添加的创建对象的注解生效,必须先在指定的基本包中进行扫描注解。

2.9.3、 属性注入@Vaule

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

如下:

package com.kkb.pojo;

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


@Component
public class Team {
    @Value("1005")
    private Integer id;
    @Value("首钢")
    private String name;
    @Value("北京")
    private String location;

    @Override
    public String toString() {
        return "Team{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", location='" + location + '\'' +
                '}';
    }

    public Team() {
        System.out.println("spring容器创建对象的方式1:通过默认的构造方法");
        System.out.println("Team的默认构造方法被调用:id="+id+",name="+name+", location="+location);
    }

    public Team(Integer id, String name, String location) {
        this.id = id;
        this.name = name;
        this.location = location;
        System.out.println("spring容器创建对象的方式2:通过带参的构造方法");
        System.out.println("id="+id+",name="+name+", location="+location);
    }


}

创建测试类:

@Test
    public void test() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation.xml");
        Team team = (Team) applicationContext.getBean("team");
        System.out.println(team);
    }

运行结果:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=63405:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test5,test
TeamController-------默认的构造方法
TeamDao------默认的构造方法
spring容器创建对象的方式1:通过默认的构造方法
Team的默认构造方法被调用:id=null,name=null, location=null
TeamService------默认的构造方法
Team{id=1005, name='首钢', location='北京'}

Process finished with exit code 0

2.9.4、byType自动注入@Autowired

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

我们先在没加@Autowirde时,运行一下TeamService的方法我们看一下运行结果

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=63529:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test5,test1
TeamController-------默认的构造方法
TeamDao------默认的构造方法
spring容器创建对象的方式1:通过默认的构造方法
Team的默认构造方法被调用:id=null,name=null, location=null
TeamService------默认的构造方法

java.lang.NullPointerException
	at com.kkb.service.TeamService.add(TeamService.java:18)
	at com.kkb.Test5.test1(Test5.java:27)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)


Process finished with exit code -1

说是空指针异常,那么我们接下来用一下@Autowired

我们看代码:

package com.kkb.service;

import com.kkb.dao.TeamDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class TeamService {
    @Autowired
    private TeamDao teamDao;

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

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

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

    public TeamDao getTeamDao() {
        return teamDao;
    }

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

我们先看一下测试类吧:

@Test
    public void test1() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("annotation.xml");
        TeamService teamService = (TeamService) applicationContext.getBean("teamService");
        teamService.add();
    }

来运行一下:

"C:\Program Files\Java\jdk-11.0.6\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar=63552:E:\java IDEA\idea\ideaIU-2020.1.4.win\bin" -Dfile.encoding=UTF-8 -classpath "E:\java IDEA\idea\ideaIU-2020.1.4.win\lib\idea_rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit5-rt.jar;E:\java IDEA\idea\ideaIU-2020.1.4.win\plugins\junit\lib\junit-rt.jar;E:\java IDEA\MySpring\spring01\target\test-classes;E:\java IDEA\MySpring\spring01\target\classes;E:\maven\maven_repository\junit\junit\4.12\junit-4.12.jar;E:\maven\maven_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\maven\maven_repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;E:\maven\maven_repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kkb.Test5,test1
TeamController-------默认的构造方法
TeamDao------默认的构造方法
spring容器创建对象的方式1:通过默认的构造方法
Team的默认构造方法被调用:id=null,name=null, location=null
TeamService------默认的构造方法
TeamDao---- add----
TeamService----add----

Process finished with exit code 0

运行成功

2.9.4、byName自动注入@Autowired和@Qualifier

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

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

2.9.5、自动注入@Resource

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

1、byType注入引用类型属性

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

2、byName注入引用类型属性

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

用法基本和@Autowired用法一样,小白就再在这里过多解释了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值