Spring框架学习笔记02 -利用组件注解符精简Spring配置文件

本文介绍了如何通过使用@Component注解来精简Spring配置文件,避免XML配置的臃肿。同时,通过面向接口的方式优化程序,实现骑士和任务的松耦合,提高代码的灵活性。在测试类中展示了如何通过注解装配Bean并进行测试。此外,还提出了课堂练习,涉及不同骑士执行不同任务的场景。
摘要由CSDN通过智能技术生成

一.课程引入

上一讲,我们采用XML配置文件的方式使用Spring容器管理Bean对象,最后给出一个思考题:“如果我们有几十个类要创建Bean,采用XML配置方式,会不会让Spring配置文件显得很臃肿,怎么解决这个问题呢?”,这一讲,我们准备利用组件注解符精简Spring配置文件。

  • 配置:configuration
  • 注解:annotation

二.打开第一讲项目

在这里插入图片描述

三、利用组件注解符精简Spring配置文件

1.创建net.tzj.spring.lesson02包

在这里插入图片描述

2.将lesson01子包的四个类拷贝到lesson02子包

在这里插入图片描述

3.修改杀龙任务类 - SlayDragonQuest

  • 业务Bean的配置可用注解符:@Component - 组件 (@Service - 服务、@Repository -
    仓库、@Mapper - 映射器、@Controller - 控制器)

@component (把普通pojo实例化到spring容器中,相当于配置文件中的)
在探究@component前先了解一下注解?何为注解?注解本质上就是一个类,开发中我们可以使用注解 取代 xml配置文件

package net.tzj.spring.lesson02;

import org.springframework.stereotype.Component;

/**
 * 功能:杀龙任务类
 * 作者:唐梓杰
 * 日期:2021年3月31日
 */
@Component //添加组件注解符,交给spring容器管理,没有设置参数,那么组件默认名称为:slayDragonQuest
public class SlayDragonQuest {
    public void embark(){
        System.out.println("执行杀龙任务");
    }
}

注:添加组件注解符@component,交给spring容器管理,没有设置参数,那么组件默认名称为:slayDragonQuest

4.修改救美任务类 - RescueDamselQuest

package net.tzj.spring.lesson02;

import org.springframework.stereotype.Component;

/**
 * 功能:救美任务类
 * 作者:唐梓杰
 * 日期:4.7
 */
@Component
public class RescueDamselQuest {
    public void embark(){
        System.out.println("执行救美任务");
    }
}

5.修改勇敢骑士类 - BraveKnight

  • 注意:删除setSlayDragonQuest()方法,因为已经通过自动装配注解设置了勇敢骑士的杀龙任务属性。
  • 查看@Component注解源码
package net.tzj.spring.lesson02;

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

/**
 * 功能:勇敢骑士类
 * 作者:唐梓杰
 * 日期:2021年03月31日
 */
@Component("Mike") //添加组件解注符,设置参数"mike",对应的就是spring配置文件里bean元素的id值
public class BraveKnight {
    @Autowired //主动装配注解符(可用@Resource或@Inject注解符替换)
    private SlayDragonQuest slayDragonQuest;

//    public void setSlayDragonQuest(SlayDragonQuest slayDragonQuest){
//
//        this.slayDragonQuest = slayDragonQuest;
//    }

    public void embarkOnQuest(){
        slayDragonQuest.embark();

    }
}

@Component(“Mike”) //添加组件解注符,设置参数"mike",对应的就是spring配置文件里bean元素的id值(不设置默认就是类的名称,设置就可以使用mike来调用)

@Autowired 自动装配程序,就不用写装配了 //主动装配注解符(可用@Resource或@Inject注解符替换)

6.修改救美骑士类 - DamselRescuingKnight

package net.tzj.spring.lesson02;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 功能:救美骑士类
 * 作者:唐梓杰
 * 日期:4.7
 */

    @Component
public class DamselRescuingKnight {
        @Resource
    private RescueDamselQuest rescueDamselQuest;

//    public DamselRescuingKnight(RescueDamselQuest rescueDamselQuest){
//        this.rescueDamselQuest = rescueDamselQuest;
//    }

    public void embarkOnQuest(){
        rescueDamselQuest.embark();
    }
}

注意:删除了构造方法,因为已经通过资源注解符将救美任务属性注入了救美骑士组件。
@Resource已经注入了救美方法,所以删除了构造方法

7.创建Spring配置文件

在resources目录创建xml_annotation子目录,然后在里面创建Spring配置文件 -spring-config.xml
在这里插入图片描述

@componentscan注解 即告诉spring 该去哪里扫描bean。

spring boot 如果你的其他包都在使用了@SpringBootApplication注解的main
类所在的包及其下级包,则你什么都不用做,SpringBoot会自动帮你把其他包都扫描了 如果你有一些bean所在的包,不在main
的包及其下级包,那么你需要手动加上@ComponentScan注解并指定那个bean所在的包

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

    <!--组件扫描,扫描指定包下添加了注解符的类或接口,将其生成Bean对象-->
    <context:component-scan base-package="net.tzj.spring.lesson02" />
</beans>

组件扫描:扫描指定包下添加了注解符的类(@Component、@Service、@Repository、@Mapper、@Controller),将其生成Bean对象(如下)

<context:component-scan base-package="net.tzj.spring.lesson02" />

8.创建测试类 - TestKnight

  • 在test/java里创建net.tzj.spring.lesson2包,在包里创建TestKnight类
    在这里插入图片描述
package net.tzj.spring.lesson02;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
功能:测试骑士类
作者:tzj
时间:4.12

 */
package net.tzj.spring.lesson02;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 功能:测试骑士类
 * 作者:tzj
 */
public class TestKnight {
    private ClassPathXmlApplicationContext context; // 基于类路径XML配置文件的应用容器

    @Before
    public void init() {
        // 基于Spring配置文件创建应用容器
        context = new ClassPathXmlApplicationContext("xml_annotation/spring-config.xml");
    }

    @Test
    public void testKnight() {
        // 根据名称从应用容器里获取勇敢骑士对象
        BraveKnight knight1 = (BraveKnight) context.getBean("Mike");
        // 勇敢骑士执行任务
        knight1.embarkOnQuest();
        // 根据名称从应用容器里获取救美骑士对象
        DamselRescuingKnight knight2 = (DamselRescuingKnight) context.getBean("damselRescuingKnight");
        // 救美骑士执行任务
        knight2.embarkOnQuest();
    }

    @After
    public void destroy() {
        // 关闭应用容器
        context.close();
    }
}

四、程序优化 - 面向接口

  • Spring框架可以方便地管理Bean及其相互依赖。为了模块之间实现松耦合,一般采用面向接口的方式。多种骑士,多种任务,可以任意搭配。为了实现这个效果,我们应该抽象出两个接口:骑士接口(Knight)和任务接口(Quest)。骑士接口有两个实现类:BraveKnightDamselRescuingKnight;任务接口有两个实现类:SlayDragonQuestRescueDamselQuest

(一)创建任务接口 - Quest

在这里插入图片描述

package net.tzj.spring.lesson02;
/*
功能:任务接口
作者:tzj
日期:4.12
 */
public interface Quest {
    void embark();
}

(二)创建骑士接口 - Knight

package net.tzj.spring.lesson02;
/*
功能:骑士接口
作者:tzj
日期:4.12
 */
public interface Knight {
    void embarkOnQuest();
}

(三)修改杀龙任务类 - SlayDragonQuest

  • 让杀龙任务类实现任务接口
    在这里插入图片描述

(四)修改救美任务类 - RescueDamselQuest

  • 让救美任务类实现任务接口
  • 在这里插入图片描述

(五)修改勇敢骑士类 - BraveKnight

在这里插入图片描述

注意:SlayDragonQuest类改成了Quest接口,这样就可以给该骑士自动装配任何任务(实现了Quest接口的Bean),增加了程序的灵活性。

(六)修改救美骑士类 - DamselRescuingKnight

  • 让救美骑士类实现骑士接口

在这里插入图片描述

(七)修改测试类 - TestKnight

在这里插入图片描述

(八)再修改测试类 - TestKnight

package net.tzj.spring.lesson02;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
功能:测试骑士类
作者:tzj
时间:4.12

 */
public class Testknight {
    private ClassPathXmlApplicationContext context; //基于路径xml设置文件的应用容器

    @Before
    public void init(){
        //基于Spring配置文件创建应用容器
        context  = new ClassPathXmlApplicationContext("xml_annotation/spring-config.xml");
    }
    @Test
    public void testBraveKnight(){
        //根据名称从应用容器里获取勇敢骑士对象
        Knight knight = (BraveKnight) context.getBean("Mike"); //父接口变量指向实现类对象
        // 勇敢骑士执行任务
        knight.embarkOnQuest();
    }
    @Test
    public void testDamselRescuingKnight(){
        //根据名称从应用容器里获取救美骑士对象
        Knight knight = (DamselRescuingKnight) context.getBean("damselRescuingKnight"); //父接口变量指向实现类对象
        //救美骑士执行任务
        knight.embarkOnQuest();
    }


    @After
    public void destory(){
        //关闭应用容器
        context.close();

    }}

在这里插入图片描述
运行结果:
在这里插入图片描述
五、课堂练习

  • 任务1、两种骑士交换执行任务。 要求勇敢骑士去救美,要求救美骑士去杀龙。

  • 任务2、两种骑士都执行两项任务。 要求勇敢骑士先执行杀龙任务,再执行救美任务。 要求救美骑士先执行救美任务,再执行杀龙任务。

  • 任务3、两种骑士再交换执行任务。 要求勇敢骑士完成杀龙任务,救美骑士完成救美任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值