IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring——Ioc中基于XMl的DI(Ioc核心 2) -> 正文阅读

[Java知识库]Spring——Ioc中基于XMl的DI(Ioc核心 2)

目录

1.基于注解的 DI概念

1.1指定多个包的三种方式:

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

1.1.2? 指定 base-package 的值使用分隔符

1.1.3 . base-package 是指定到父包名

?2.注解类型的使用

?2.1定义 Bean 的注解@Component、@Value

2.2 byType 自动注入@Autowired(默认)

?2.3?byName 自动注入@Autowired 与@Qualifier

2.4JDK 注解@Resource 自动注入?

3. 注解与 XML 的对比


1.基于注解的 DI概念

注解类型:

创建对象的注解:@Component、@Repository、@Service、@Controller。(来自Spring框架)
简单类型的对象属性赋值:@Value。(来自Spring框架)
引用类型的对象属性赋值:@Autowired、@Qualifier。(来自Spring框架)
引用类型的对象属性赋值:@Resource。(来自JDK)
对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。Spring 中使用注解,需要在原有 Spring 运行环境基础上再做一些改变。需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。?

1.1指定多个包的三种方式:

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

<!--
    声明组件扫描器:使用注解必须加上这个语句
    component-scan: 组件扫描器,组件是Java对象
    属性base-package: 表示项目中的包名
    框架会扫描这个包和子包中的所有类,找到类中的所有注解,
    遇到注解后,按照注解表示的功能,去创建对象、给属性赋值
-->
<context:component-scan base-package="com.liuhaiyang.ba01" />
<context:component-scan base-package="com.liuhaiyang.ba02" />

1.1.2? 指定 base-package 的值使用分隔符

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

<!-- 可以使用分隔符(;或者,)指定多个包 -->
<context:component-scan base-package="com.liuhaiyang.ba01;com.liuhaiyang.ba02" />
<context:component-scan base-package="com.liuhaiyang.ba03,com.liuhaiyang.ba04" />

1.1.3 . base-package 是指定到父包名

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

<!-- 也可以指定父包 -->
<context:component-scan base-package="com.liuhaiyang" />

?2.注解类型的使用

?2.1定义 Bean 的注解@Component、@Value

@Component: 表示创建对象,对象放到容器中,作用是 <bean>
? ? ? ? ? 属性: value,表示对象名称,也就是 <bean> 标签中的 id 属性值
? ? ? ? ? 位置: 在类的上面,表示创建此类的对象

与@Component功能相同的创建对象的注解:

????????@Repository : 放在dao接口的实现类上面,能访问数据库
????????@Service : 放在service的实现类上面,具有事务的功能
????????@Controller : 放在controller的实现类上面,能够接收请求,把请求的处理结果显示给用户。

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

简单类型的属性赋值:@Value
? ? ?? 属性: value,表示属性值,可以省略
? ? ?? 位置:1) 在属性定义的上面,无需set方法,推荐使用
? ? ? ? ? ?? ? ? ?2) 在set方法上面

实体类:

package com.liuhaiyang.bao01;


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

/**
 * @Component: 表示创建对象,对象放到容器中,作用是<bean>
 *      属性:value,表示对象名称,也就是bean的id属性
 *      位置:在类的上面,表示创建此类的对象。
 *
 * @Component(value =”mystudent“)等同于
 * <bean id="myStudent" clas="com.liuhaiyang.bao01.student">
 *
 * @Component 功能相同的创建对象的注解
 * 1.@Repository:放到dao接口的实现类上面,表示创建dao对象,持久层对象,能访问数据库
 * 2.@Service:   放在业务层接口的实现类上面,表示创建业务对象,业务层对象有事务的功能
 * 3.Controller: 放在控制器类的上面,表示创建控制器对象。属于表示层对象。
 *               控制器对象能接受请求,把请求的处理结果显示给用户。
 *
 */
//@Component(value = "myStudent")
    //默认名称:类名首字母小写  @Component
//可以省略value
@Component("myStudent")
public class Student {
    //使用外部属性文件中的数据,语法@value("${key}")
    @Value("张三")
    private String name;
    @Value("20")
    private int age;
    public Student(){
        System.out.println("调用了无参构造!!");
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--    声明组件扫描器:使用注解必须要加入这句话
        component-scan:翻译过来是组件扫描器,组件是Java对象。
            属性:base-package 注解在你的项目中的包名。
            框架会扫描这个包和子包中的所有类,找到类中的所有注解。
            遇到注解后,按照注解表示的功能,去创建对象,给属性赋值。
-->
    <context:component-scan base-package="com.liuhaiyang.bao01"/>
</beans>

测试类:

@Test
    public void mytest01(){
        String confed="applicationContext.xml";
        ApplicationContext cxt=new ClassPathXmlApplicationContext(confed);
        Student student=(Student) cxt.getBean("myStudent");
        System.out.println(student);
    }

结果截图:

2.2 byType 自动注入@Autowired(默认)

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

属性:required:boolean类型的属性,默认为true
? ? ? ? ? ? true:spring在创建容器对象时,会检查引用类型是否赋值成功,如果赋值失败,终止程序运行并报错。
? ? ? ? ? ? false:如果引用类型赋值失败,程序正常执行不会报错,此时引用类型的值为null。

位置:1)在属性定义的上面,无需set方法,推荐使用
? ? ? ? ? ?2)在set方法上面
实体类:

package com.liuhaiyang.bao03;

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

@Component("myschool")
public class School {
    @Value("厕所蹲大学")
    private String  name;
    @Value("北京丰台区")
    private  String  bname;

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

    public void setBname(String bname) {
        this.bname = bname;
    }

    @Override
    public String  toString() {
        return "School{" +
                "name='" + name + '\'' +
                ", bname='" + bname + '\'' +
                '}';
    }
}
package com.liuhaiyang.bao03;


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

@Component("myStudent")
public class Student {
    @Value("李四")
    private String name;
    @Value(value = "23")
    private int age;
    /**
     * 引用类型 @Autowired: spring框架提供的,给引用类型赋值的,使用自动注入原理。
     *          支持byName,byType。默认是byType
     *          位置:1.在属性定义的上面,无需set方法,推荐使用
     *               2.在set方法上面
     *          属性:required:boolean类型的属性,默认是true  spring在启动的时候创建容器对象。
     *          会检查引用类型是否赋值成功。当时true时,终止程序,并报错。 当为false:引用类型赋值失效,
     *          程序正常执行,不报错引用类型值为null
     *
     *byName自动注入: 1.@Autowired:给引用类型赋值
     *              2.@Qualifer(value="bean的id"):从容器中找到指定名称的对象,把这个对象赋值给引用类型。
     */
    @Autowired()
    private School school;

    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Student(){
        System.out.println("调用了无参构造!!");
    }

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

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.liuhaiyang.bao03"/>
</beans>

测试类

@Test
    public void mytest01(){
        String confed="applicationContext.xml";
        ApplicationContext cxt=new ClassPathXmlApplicationContext(confed);
        Student student=(Student) cxt.getBean("myStudent");
        System.out.println(student);
    }

结果截图:

?2.3?byName 自动注入@Autowired 与@Qualifier

?????????spring框架提供的,给引用类型赋值的,使用自动注入原理。支持byName、byType,默认是byType

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

以为代码上面代码基本一致,所以写不一样的

Student实体类:

package com.liuhaiyang.bao03;


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

@Component("myStudent")
public class Student {
    @Value("李四")
    private String name;
    @Value(value = "23")
    private int age;
    /**
     * 引用类型 @Autowired: spring框架提供的,给引用类型赋值的,使用自动注入原理。
     *          支持byName,byType。默认是byType
     *          位置:1.在属性定义的上面,无需set方法,推荐使用
     *               2.在set方法上面
     *          属性:required:boolean类型的属性,默认是true  spring在启动的时候创建容器对象。
     *          会检查引用类型是否赋值成功。当时true时,终止程序,并报错。 当为false:引用类型赋值失效,
     *          程序正常执行,不报错引用类型值为null
     *
     *byName自动注入: 1.@Autowired:给引用类型赋值
     *              2.@Qualifer(value="bean的id"):从容器中找到指定名称的对象,把这个对象赋值给引用类型。
     */
    @Autowired(required = false)
    @Qualifier("myschoolAAAA")  //无先后顺序之分
    private School school;

    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Student(){
        System.out.println("调用了无参构造!!");
    }

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

其他代码是一样的。就不写了,掌握即可。

2.4JDK 注解@Resource 自动注入?

引用类型:@Resource,来自jdk中,给引用类型赋值,支持byName、byType,默认是byName。Spring框架支持这个注解。

位置:1) 在属性定义的上面,无需set方法,推荐使用
? ? ? ? ? 2) 在set方法上面

@Resource:先使用byName赋值,如果赋值失败,再使用byType
@Resource(name="mySchool"):表示只使用byName
如果使用jdk1.8,则带有@Resource注解;如果高于jdk1.8,则没有这个注解。如需使用,需要在pom.xml文件中加入依赖


<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

实体类:

package com.liuhaiyang.bao04;

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

@Component("myschool")
public class School {
    @Value("厕所蹲大学")
    private String  name;
    @Value("tianj丰台区")
    private  String  bname;

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

    public void setBname(String bname) {
        this.bname = bname;
    }

    @Override
    public String  toString() {
        return "School{" +
                "name='" + name + '\'' +
                ", bname='" + bname + '\'' +
                '}';
    }
}
package com.liuhaiyang.bao04;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Component("myStudent")
public class Student {
    @Value("李四")
    private String name;
    @Value(value = "23")
    private int age;

    /**引用类型
     * @Resource: 来自jdk中,给引用类型赋值的,支持byName,byType。默认是byName。Spring支持这个注解的使用
     *      位置:1.在属性上面定义。无需set方法,推荐
     *           2.在set方法的上面使用
     * 注意:使用jdk1.8带有@Resource注解,高于jdk1.8则没有这个注解,需要加入一个依赖
     */
    //先使用byName方式赋值(就是查找myschool),如果失败了,在使用byType(就是查找School类)
    @Resource(name = "myschool")
    private School school;

    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Student(){
        System.out.println("调用了无参构造!!");
    }

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

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.liuhaiyang.bao04"/>
</beans>

测试类

 @Test
    public void mytest03(){
        String confed="applicationContext.xml";
        ApplicationContext cxt=new ClassPathXmlApplicationContext(confed);
        Student student=(Student) cxt.getBean("myStudent");
        System.out.println(student);
    }

结果截图:

3. 注解与 XML 的对比

注解方式

优点:方便、直观、高效(代码少,没有配置文件的书写那么复杂)?。

缺点:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。

XML方式

优点:1.配置和代码是相分离的。

? ? ? ? ? ?2.在xml中做修改,无需编译代码,只需重启服务器即可将新的配置加载。

缺点:编写麻烦,效率低,如果面对大型项目就显得过于复杂。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章           查看所有文章
加:2021-08-02 20:46:54  更:2021-08-02 20:47:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 13:40:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码