[Spring Framework]注解开发③(依赖注入)

简介: 注解开发③(依赖注入)

@[TOC]

自动装配

Spring为了使用注解简化开发,并没有提供构造函数注入setter注入对应的注解,只提供了自动装配的注解实现。

项目环境介绍

我们有一个Spring配置类:

@Configuration
@ComponentScan("impl")
public class SpringConfig {

}

另个接口,两个实现类,且他们均在impl文件夹中:

public interface BookDao {
    public void save();
}
@Repository
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ..." );
    }
}
public interface BookService {
    public void save();
}
@Service
public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

工程结构:
在这里插入图片描述

注解实现按照类型注入

在BookServiceImpl类的bookDao属性上添加@Autowired注解

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;
    
//      public void setBookDao(BookDao bookDao) {
//        this.bookDao = bookDao;
//    }
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

然后我们运行测试demo:

public class App8 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookService bookService = ctx.getBean("bookService", BookService.class);
        bookService.save();
    }
}

结果成功:
在这里插入图片描述

@Autowired可以写在属性上,也可也写在setter方法上,最简单的处理方式是 写在属性上并将setter方法删除掉

==为什么setter方法可以删除呢?==

这是因为自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值,普通反射只能获取public修饰的内容,暴力反射除了获取public修饰的内容还可以获取private修改的内容,所以此处无需提供setter方法

@Autowired是按照类型注入,那么对应BookDao接口如果有多个实现类,显然这里就不适用了,因为按照类型注入就无法区分到底注入哪个对象。

比如我们添加一个类:

@Repository
public class BookDaoImpl2 implements BookDao {
    public void save() {
        System.out.println("book dao save ...2");
    }
}

如果我们直接运行控制台会报错NoUniqueBeanDefinitionException
在这里插入图片描述

所以我们这里使用按照名称注入

注解实现按照名称注入

==在使用名称注入之前==,我们先来看一个特殊情况:

我们先给两个Dao类分别起个名称:

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ..." );
    }
}
@Repository("bookDao2")
public class BookDaoImpl2 implements BookDao {
    public void save() {
        System.out.println("book dao save ...2" );
    }
}

我们再运行就成功了:
在这里插入图片描述

此时就可以注入成功,但是得思考个问题:

  • @Autowired是按照类型注入的,给BookDao的两个实现起了名称,它还是有两个bean对象,为什么不报错?
  • @Autowired默认按照类型自动装配,如果IOC容器中同类的Bean找到多个,就按照变量名和Bean的名称匹配。因为变量名叫bookDao而容器中也有一个booDao,所以可以成功注入。

也就是说,如果是下图中的情况,就不行了:
在这里插入图片描述
因为按照类型会找到多个bean对象,此时会按照bookDao名称去找,因为IOC容器只有名称叫bookDao1bookDao2,所以找不到,会报NoUniqueBeanDefinitionException

接下来我们使用名称注入:

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    @Qualifier("bookDao1")
    private BookDao bookDao;
    
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

@Qualifier注解后的值就是需要注入的bean的名称。

==注意:@Qualifier不能独立使用,必须和@Autowired一起使用==

结果成功:
在这里插入图片描述

简单数据类型注入

引用类型看完,简单类型注入就比较容易懂了。简单类型注入的是基本数据类型或者字符串类型,下面在BookDaoImpl类中添加一个name属性,用其进行简单类型注入

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    private String name;
    public void save() {
        System.out.println("book dao save ..." + name);
    }
}

数据类型换了,对应的注解也要跟着换,这次使用@Value注解,将值写入注解的参数中就行了

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    @Value("csdn")
    private String name;
    public void save() {
        System.out.println("book dao save ..." + name);
    }
}

结果:
在这里插入图片描述

注意数据格式要匹配,如将"abc"注入给int值,这样程序就会报错。

介绍完后,会有一种感觉就是这个注解好像没什么用,跟直接赋值是一个效果,还没有直接赋值简单,所以这个注解存在的意义是什么?

注解读取properties配置文件

@Value一般会被用在从properties配置文件中读取内容进行使用,具体如何实现?

步骤1:resource下准备properties文件

jdbc.properties

name=csdn888

步骤2: 使用注解加载properties配置文件

在配置类上添加@PropertySource注解

@Configuration
@ComponentScan("impl")
@PropertySource("jdbc.properties")
public class SpringConfig {
}

步骤3:使用@Value读取配置文件中的内容

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    @Value("${name}")
    private String name;
    public void save() {
        System.out.println("book dao save ..." + name);
    }
}

注意:

  • 如果读取的properties配置文件有多个,可以使用@PropertySource的属性来指定多个

    @PropertySource({"jdbc.properties","xxx.properties"})
  • @PropertySource注解属性中不支持使用通配符*,运行会报错

    @PropertySource({"*.properties"})
  • @PropertySource注解属性中可以把classpath:加上,代表从当前项目的根路径找文件

    @PropertySource({"classpath:jdbc.properties"})

总结

知识点1:@Autowired

名称 @Autowired
类型 属性注解 或 方法注解(了解) 或 方法形参注解(了解)
位置 属性定义上方 或 标准set方法上方 或 类set方法上方 或 方法形参前面
作用 为引用类型属性设置值
属性 required:true/false,定义该属性是否允许为null

知识点2:@Qualifier

名称 @Qualifier
类型 属性注解 或 方法注解(了解)
位置 属性定义上方 或 标准set方法上方 或 类set方法上方
作用 为引用类型属性指定注入的beanId
属性 value(默认):设置注入的beanId

知识点3:@Value

名称 @Value
类型 属性注解 或 方法注解(了解)
位置 属性定义上方 或 标准set方法上方 或 类set方法上方
作用 为 基本数据类型 或 字符串类型 属性设置值
属性 value(默认):要注入的属性值

知识点4:@PropertySource

名称 @PropertySource
类型 类注解
位置 类定义上方
作用 加载properties文件中的属性值
属性 value(默认):设置加载的properties文件对应的文件名或文件名组成的数组
相关文章
|
17天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
36 0
|
24天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
45 4
SpringBoot必须掌握的常用注解!
|
3天前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
17 2
|
15天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
28 2
|
26天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
84 2
|
26天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
36 1
|
2月前
|
XML Java 数据格式
提升效率!Spring Boot 开发中的常见失误轻松规避
本文深入探讨了在 Spring Boot 开发中常见的失误,包括不当使用注解、不良异常处理、低效日志记录等,提供了有效的规避策略,帮助开发者提升代码质量和系统性能,构建更健壮、高效的应用程序。
|
20天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
31 0
|
21天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
13 0
|
2月前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。