【SpringFramework】Spring IoC-基于注解的实现

简介: 本文主要记录基于Spring注解实现IoC容器和DI相关知识。

注解的基础知识,请查阅 (四)【乙】Java注解

一、启用组件自动扫描

(1)使用注解管理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  http://www.springframework.org/schema/context/spring-context.xsd">
    <!--开启组件扫描功能-->
    <!--1. 基本方式:全包扫描-->
    <context:component-scan base-package="com.sheeprunner.spring.c.ioc_annotation" />
</beans>

(2)关于context:component-scan的几种扫描方式

  1. 基本方式:全包扫描
<context:component-scan base-package="com.sheeprunner.spring.c.ioc_annotation" />
  1. 排除指定组件:context:exclude=filter type="annotation"/"assignable" expression="需排除包路径"
<context:component-scan base-package="com.sheeprunner.spring.c.ioc_annotation">
    <!-- context:exclude-filter标签:指定排除规则 -->
    <!-- 
         type:设置排除或包含的依据
        type="annotation",根据注解排除,expression中设置要排除的注解的全类名
        type="assignable",根据类型排除,expression中设置要排除的类型的全类名
    -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    <!--<context:exclude-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
</context:component-scan>
  1. 仅扫描指定组件:context:include=filter type="annotation"/"assignable" expression="需扫描包路径"
<context:component-scan base-package="com.atguigu" use-default-filters="false">
    <!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 -->
    <!-- use-default-filters属性:取值false表示关闭默认扫描规则 -->
    <!-- 此时必须设置use-default-filters="false",因为默认规则即扫描指定包下所有类 -->
    <!-- 
         type:设置排除或包含的依据
        type="annotation",根据注解排除,expression中设置要排除的注解的全类名
        type="assignable",根据类型排除,expression中设置要排除的类型的全类名
    -->
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    <!--<context:include-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
</context:component-scan>

(3)使用注解定义Bean

Spring提供了四个注解,直接标注在Java类上,用于将这些类定义为Spring Bean。

  • @Component:用于Spring中的Bean,是一个泛华的概念,进表示容器中的一个组件(Bean),可用于任何层次的类上,例如Service/Dao/Controller
  • @Repository:用于数据访问层(Dao层)的类,功能与@Component相同
  • @Service:用于业务层(Service层)的类,功能与@Component相同
  • @Controller:用于控制层(Controller层)的类,功能与@Component相同

(4)使用注解装配Bean

  1. @AutoWired
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
}
  • 默认根据类型装配(byType)
  • 该注解可以用在构造方法、方法、参数、字段、注解类型上,甚至如果只有一个构造函数,则该注解可以省略
  • required属性:默认为true,表示被注入的Bean必须存在,否则报错;如果required属性设置为false,表示注入Bean存在或不存在都没关系,存在就注入,不存在也不报错
  1. @Qualifier
  • 如果存在多个同类型的Bean,则使用@Qualifier指定Bean的名称,例如@Qualifier("userDao")
  • @Qualifier("")使用名称进行装配(byName)
  • 该注解搭配@Autowired注解一起使用,也可以在Bean上使用@Primary指定优先级

当存在两个Bean,而没有用@Qualifier注解指定时,编译时抛出如下异常:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookController' defined in file [D:\SheepRunner\GitProjects\springexecute\Cspring_ioc_annotation\target\classes\com\sheeprunner\spring\c\ioc_annotation\controller\BookController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookServiceImpl': Unsatisfied dependency expressed through method 'setBookDao' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.sheeprunner.spring.c.ioc_annotation.dao.BookDao' available: expected single matching bean but found 2: bookDaoImpl,bookDaoRedisImpl
  1. @Resource

@Resource注解也可以完成属性注入。那它和@Autowired注解有什么区别?

  • @Resource注解是JDK扩展包中的,也就是说属于JDK的一部分。所以该注解是标准注解,更加具有通用性。(JSR-250标准中制定的注解类型。JSR是Java规范提案。)
  • @Autowired注解是Spring框架自己的。
  • @Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name。通过name找不到的话会自动启动通过类型byType装配。
  • @Autowired注解默认根据类型装配byType,如果想根据名称装配,需要配合@Qualifier注解一起用。
  • @Resource注解用在属性上、setter方法上。
  • @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。

@Resource注解属于JDK扩展包,所以不在JDK当中,需要额外引入以下依赖:【如果是JDK8的话不需要额外引入依赖。高于JDK11或低于JDK8需要引入以下依赖。

①场景一:根据name注入

修改UserDaoImpl类

package com.atguigu.spring6.dao.impl;
import com.atguigu.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository("myUserDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void print() {
        System.out.println("Dao层执行结束");
    }
}
②场景二:name未知注入

修改UserDaoImpl类

package com.atguigu.spring6.dao.impl;
import com.atguigu.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository("myUserDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void print() {
        System.out.println("Dao层执行结束");
    }
}

@Resource注解:默认byName注入,没有指定name时把属性名当做name,根据name找不到时,才会byType注入。byType注入时,某种类型的Bean只能有一个

(5)全注解

全注解开发就是不再需要Spring配置文件,而是通过一个配置类来替代。
使用@Configuration注解来标识配置类,@ComponentScan("com.sheeprunner.spring.c")表示需要扫描的包路径。

二、原理

  1. 反射
    详见  (四)【甲】Java反射
  2. 注解

详见   (四)【乙】Java注解

  1. 手写实现Spring IoC
    基于注解和反射实现IoC容器,注册组件及装配Bean
目录
打赏
0
22
21
1
153
分享
相关文章
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
124 26
【SpringFramework】Spring整合JUnit
本文简述Spring整合JUnit单元测试组件的通用方法,可以简化Spring框架测试。
98 14
SpringBoot缓存注解使用
Spring Boot 提供了一套方便的缓存注解,用于简化缓存管理。通过 `@Cacheable`、`@CachePut`、`@CacheEvict` 和 `@Caching` 等注解,开发者可以轻松地实现方法级别的缓存操作,从而提升应用的性能和响应速度。合理使用这些注解可以大大减少数据库的访问频率,优化系统性能。
196 89
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
185 73
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
119 69
|
23天前
|
SpringBoot:SpringBoot通过注解监测Controller接口
本文详细介绍了如何通过Spring Boot注解监测Controller接口,包括自定义注解、AOP切面的创建和使用以及具体的示例代码。通过这种方式,可以方便地在Controller方法执行前后添加日志记录、性能监控和异常处理逻辑,而无需修改方法本身的代码。这种方法不仅提高了代码的可维护性,还增强了系统的监控能力。希望本文能帮助您更好地理解和应用Spring Boot中的注解监测技术。
58 16
【SpringFramework】Spring事务
本文简述Spring中数据库及事务相关衍伸知识点。
52 9
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
61 12

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等