Spring之基于注解实现Ioc

78 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解java实现单链表,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan

基于注解实现Ioc

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

声明Bean的注解 @Component

在类上添加注解@Component表示该类创建对象的权限交给Spring容器。注解的value属性用于指定bean的id值,value可以省略。 @Component 不指定 value 属性,bean 的 id 是类名的首字母小写。 除此之外,Spring中还提供了其他3个用于创建对象的注解: @Repository : 用于dao实现类的的注解 @Service: 用户service实现类的注解 @Controller: 用于controller实现类的注解 这三个注解与@Component 都可以创建对象,但这三个注解还有其他的含义,@Service创建业务层对象,业务层对象可以加入事务功能,@Controller 注解创建的对象可以作为处理器接收用户的请求。 @Repository,@Service,@Controller 是对@Component 注解的细化,标注不同层的对象。即持久层对象,业务层对象,控制层对象。

属性注入@Vaule

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

image-20220703110434040

byType自动注入@Autowired

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

byName自动注入@Autowired和@Qualifier

需要在引用属性上联合使用注解@Autowired 与@Qualifier。@Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值。类中无需 set 方法,也可加到 set 方法上。 @Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。

image-20220703110632242

自动注入@Resource

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

byType注入引用类型属性

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

byName注入引用类型属性

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

annocation.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"
        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">
 ​
     <!--关于元注解的使用
         @Component(又叫做万能注解)  一般用于实体类
         @Repository 一般用于Dao
         @Service    一般用于Service
         @Controller 一般用于Controller
         其作用以及语法一样
     -->
     <!--使用多个context:component-scan指定不同的包路径
         需要在在beans中添加该命名空间,否则不生效:
             xmlns:context="http://www.springframework.org/schema/context"
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd"
             来使用context
                 指定扫描,需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。
                 如果没有报扫描,添加的创建对象的注解不生效。
     -->
     <!--这个意思是指在这些包中,添加了@Component注解的对象就由Spring进行创建-->
     <context:component-scan base-package="com.jinhuan"/>
 ​
     <!--多个包扫描
         1、
         <context:component-scan base-package="com.jinhuan.pojo"/>
         <context:component-scan base-package="com.jinhuan.dao"/>
         <context:component-scan base-package="com.jinhuan.service"/>
 ​
         2、用,隔开 或者 分号;  或者 “ ”(空格,不推荐使用空格)
         <context:component-scan base-package="com.jinhuan.pojo,com.jinhuan.dao,com.jinhuan.service"/>
         <context:component-scan base-package="com.jinhuan.pojo;com.jinhuan.dao;com.jinhuan.service"/>
         <context:component-scan base-package="com.jinhuan.pojo com.jinhuan.dao com.jinhuan.service"/>
 ​
         3、直接扫描父包,不建议使用过顶级的父包!最好是直接父包
         <context:component-scan base-package="com.jinhuan"/>
     -->
 ​
 </beans>

Team

 package com.jinhuan.pojo;
 ​
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/5/9 15:39
  * Description:球队的实体类
  */
 @Component
 public class Team {
     @Value("8080")
     private Integer id;
     @Value("公牛")
     private String name;
     @Value("芝加哥")
     private String location;
 ​
     public void init(){
         System.out.println("Team....init().....");
     }
 ​
     public void destory(){
         System.out.println("Team....destory().....");
     }
 ​
     public Team() {
         System.out.println("无参数的构造方法: 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("带参数的构造方法: id->"+id+";name->"+name+";location->"+location);
     }
 ​
     @Override
     public String toString() {
         return "Team{" +
                 "id=" + id +
                 ", name='" + name + ''' +
                 ", location='" + location + ''' +
                 '}';
     }
 }
 ​

TeamDao

 package com.jinhuan.dao;
 ​
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Repository;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/5/9 19:45
  * Description:
  */
 //@Component(value = "teamDao")
 @Repository(value = "teamDao")
 ​
 /**
  * @Component标识在类上,表示对象有Spring容器进行创建 value属性表示id值
  * 等价于 <bean id="teamDao" class="com.jinhuan.dao.TeamDao"/>
  * (value = "teamDao")value可以省略("teamDao")
  * (value = "teamDao")整体也可以省略 省略后默认的id就是类名的首字母小写 teamDao
   */
 ​
 ​
 public class TeamDao {
     public void add(){
         System.out.println("Team-----------add()-----------");
     }
 ​
     public TeamDao() {
         System.out.println("TeamDao-------默认构造方法被使用");
     }
 }
 ​

TeamController

 package com.jinhuan.controller;
 ​
 import com.jinhuan.service.TeamService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 ​
 import javax.annotation.Resource;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/5/10 0:25
  * Description:
  */
 @Controller
 public class TeamController {
     /**
      * @Resource JDk的一个内置注解(>jdk1.6)
      * 默认按照名称自动装配
      * 如果名称没有想符的就按照类型自动装配
      * 属性:name【按照name匹配】type【按照类型匹配】,可以同时使用
      */
     //@Autowire
     @Resource
     private TeamService teamService;
 ​
     public TeamController() {
         System.out.println("TeamController-----------默认构造方法被使用");
     }
 ​
     public void add(){
         teamService.add();
     }
 }

TeamService

 package com.jinhuan.service;
 ​
 import com.jinhuan.dao.TeamDao;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/5/9 19:46
  * Description:
  */
 @Service
 public class TeamService {
     /**
      * @Autowired是指自动装配,默认按照类型来装配,如果非想要指定的id(按照指定名称装配),
      * 可以搭配这个注解@Qualifier,并指定value
      * @Autowired有一个属性required,默认值是true,意思是如果没有可以匹配的类型(即所需对象未创建),就直接报错
      *                              如果是false,意思是如果没有可以匹配的类型,则将该对象置为空
      */
     @Autowired(required = true)
     @Qualifier(value = "teamDao")
     private TeamDao teamDao;//new TeamDao();是原来的方法
 ​
     /**调用TeamDao中的add方法
      *
      */
     public void add(){
         teamDao.add();
     }
 ​
 ​
 ​
     /**
      * 使用Set注入
      * */
     public void setTeamDao(TeamDao teamDao) {
         this.teamDao = teamDao;
     }
 ​
     public TeamDao getTeamDao() {
         return teamDao;
     }
 ​
     /**
      * 构造注入
      * */
     public TeamService(TeamDao teamDao) {
         this.teamDao = teamDao;
     }
 ​
     public TeamService() {
         System.out.println("TeamService--------无参构造方法被使用");
     }
 ​
 }

Test

 package com.jinhuan.test;
 ​
 import com.jinhuan.controller.TeamController;
 import com.jinhuan.dao.TeamDao;
 import com.jinhuan.service.TeamService;
 import org.junit.Test;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 ​
 /**
  * @Author jinhuan
  * @Date 2022/5/10 0:35
  * Description:
  */
 public class Test04 {
     @Test
     public void test() {
         /**
          * 测试注解实现Ioc
          *
          * */
         //获取容器
         ApplicationContext ac = new ClassPathXmlApplicationContext("annocation.xml");
 ​
         //获取对象并调用方法
         System.out.println(ac.getBean("team"));
 ​
         TeamService teamService = (TeamService) ac.getBean("teamService");
         teamService.add();
 ​
         TeamDao teamDao = (TeamDao) ac.getBean("teamDao");
         teamDao.add();
 ​
         TeamController teamController = (TeamController) ac.getBean("teamController");
         teamController.add();
     }
 }