【Spring】IoC容器 控制反转 与 DI依赖注入 注解实现版本 第三期

本文详细介绍了Spring框架中基于注解管理Bean的方法,包括组件注解的使用、扫描范围的配置、不同作用域和生命周期方法,以及引用类型和基本类型属性的自动装配。同时提到虽然注解方便,但第三方依赖仍需配合XML配置。
摘要由CSDN通过智能技术生成


基于 注解 方式管理 Bean

  • 和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记
  • 具体的功能是:
    • 框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。
  • 本质上:
    • 所有一切的操作都是 Java 代码来完成的,XML 和注解只是告诉框架中的 Java 代码如何执行。

一、Bean注解标记和扫描 (IoC)

注解 (标记)+ XML(扫描)

  1. 注解方式IoC只是标记哪些类要被Spring管理
  2. 最终,我们还需要XML方式或者Java配置类方式指定注解生效的包

Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。

1.1 组件注解介绍

注解说明
@Component该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。
@Repository该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
通过查看源码我们得知,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。

@Controller、@Service、@Repository 本质上是一样,只是给开发人员看的,让我们能够便于分辨组件的作用,为了代码的可读性、程序结构严谨。

1.2 标记组件

/**
 * @Description: 普通的组件
 */
@Component
public class JavaCompontent {
}
/**
 * @Description: Controller类型组件
 */
@Controller
public class XxxController {
}
/**
 * @Description: service类型组件
 */
@Service
public class XxxService {
}
/**
 * @Description: dao层类型组件
 */
@Repository
public class XxxDao {
}

1.3 配置文件确定扫描范围

    <!-- 1. 普通配置包扫描
        base-package 扫描这个包下全部的类(可以一个包 或 多包)
       -->
    <context:component-scan base-package="com.doug.ioc01"/>
    <!-- 2. 指定包,但是排除注解   -->
    <!-- context:exclude-filter标签:指定排除规则 -->
    <!-- type属性:指定根据什么来进行排除,annotation取值表示根据注解来排除 -->
    <!-- expression属性:指定排除规则的表达式,对于注解来说指定全类名即可 -->
    <context:component-scan base-package="com.doug">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <!-- 3. 指定包,指定包含的注解   -->
    <!-- 仅扫描 = 关闭默认规则 + 追加规则 -->
	<!-- use-default-filters属性:取值false表示关闭默认扫描规则 -->
    <context:component-scan base-package="com.doug" use-default-filters="false">
     <!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>

1.4 组件BeanName问题

默认情况:
类名首字母小写就是 bean 的 id。
例如:SoldierController 类对应的 bean 的 id 就是 soldierController

使用value属性指定:

@Controller(value = "myController")
public class XxxController {
}

当注解中只设置一个属性时,value属性的属性名可以省略:

@Controller("myController")
public class XxxController {
}

二、组件(Bean)作用域和周期方法注解

@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) //单例,默认值
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) //多例  二选一
public class BeanOne {

  //周期方法要求: 方法命名随意,但是要求方法必须是 public void 无形参列表
  @PostConstruct  //注解制指定初始化方法
  public void init() {
    // 初始化逻辑
  }
}

public class BeanTwo {
  
  @PreDestroy //注解指定销毁方法
  public void cleanup() {
    // 释放资源逻辑
  }
}

三、Bean属性赋值:引用类型自动装配 (DI)

  • @Autowired注解
    • 使用此直接 自动装配 引用类型成员属性
    • 能够找到唯一的 bean:直接执行装配
    • 如果完全找不到匹配这个类型的 bean:装配失败
@Controller("myController")
public class XxxController {
    
    @Autowired
    private XxxService serviceImpl;
    
    public void show(){}
}
  • 类型匹配的 bean 不止一个
    • 没有 @Qualifier 注解:根据 @Autowired 标记位置成员变量的变量名作为 bean 的 id 进行匹配
      • 能够找到:执行装配
      • 找不到:装配失败
    • 使用 @Qualifier 注解:根据 @Qualifier 注解中指定的名称作为 bean 的id进行匹配
      • 能够找到:执行装配
      • 找不到:装配失败
@Controller("myController")
public class XxxController {

    // <property xxxservice -> 对应类型的bean装配
    //自动装配注解(DI) : 1. IOC容器中查找符合类型的组件对象 2. 设置给当前属性(DI)
    @Autowired
    @Qualifier(value = "xxxService")
    private XxxService serviceImpl;

    public void show(){}
}
  • 指定 单个 引用类型装配 使用@Autowired注解
  • 多个引用类型的 存在 使用 @Autowired + @Qualifier(指定类名)
  • @Autowired + @Qualifier(指定类名) == 注解@Resource(指定类名)
    • @Resource: 标识一个需要注入的资源,是实现Java EE组件之间依赖关系的一种方式。

使用 注解@Resource ,需要导入依赖:

<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>2.1.1</version>
</dependency>

@Resource使用 :

@Controller
public class XxxController {
    /**
     * 1. 如果没有指定name,先根据属性名查找IoC中组件xxxService
     * 2. 如果没有指定name,并且属性名没有对应的组件,会根据属性类型查找
     * 3. 可以指定name名称查找!  @Resource(name='test') == @Autowired + @Qualifier(value='test')
     */
    @Resource
    private XxxService xxxService;

    //@Resource(name = "指定beanName")
    //private XxxService xxxService;

    public void show(){
        System.out.println("XxxController.show");
        xxxService.show();
    }
}

四、Bean属性赋值:基本类型属性赋值 (DI)

@Value 通常用于注入外部化属性

1

@Component
public class JavaBean {
/*
* 1. 直接赋值
* 2. 注解赋值:
*   2.1 @Value注解  直接/读取外部配置
*           默认语法:
*               @Value("value")
*               @Value("${key}")    @Value("${key:value}")
* */

    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password:000000}")
    private String pwd;
    @Value("18")
    private int age;
    private String value = "道格";

    @Override
    public String toString() {
        return "JavaBean{" +
                "username='" + username + '\'' +
                ", pwd='" + pwd + '\'' +
                ", age=" + age +
                ", value='" + value + '\'' +
                '}';
    }
}

2
在这里插入图片描述

五、基于注解+XML方式整合三层架构组件

1述

加注解,但dao层 导入第三方类 所以还是要在xml里面配置bean
1
1


总结

1

  1. 自定义类可以使用注解方式,但是第三方依赖的类依然使用XML方式!
  2. XML格式解析效率低!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值