首页 > 编程语言 >Spring-2-深入理解Spring 注解依赖注入(DI):简化Java应用程序开发

Spring-2-深入理解Spring 注解依赖注入(DI):简化Java应用程序开发

时间:2023-08-08 22:01:45浏览次数:136  
标签:装配 Java Spring class 程序开发 public Bean 注解 ds

今日目标

掌握纯注解开发依赖注入(DI)模式

学习使用纯注解进行第三方Bean注入

1 注解开发依赖注入(DI)【重点】

问题导入

思考:如何使用注解方式将Bean对象注入到类中

1.1 使用@Autowired注解开启自动装配模式(按类型)

@Service
public class StudentServiceImpl implements StudentService {

    //创建成员对象
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    @Autowired
    private StudentDao studentDao ;

    @Override
    public void save() {
        System.out.println("Service: 添加学生信息到数据库...");
        studentDao.save();
    }
}

说明:不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。@Autowired默认按照类型自动装配,如果IoC容器中同类的Bean有多个,那么默认按照变量名和Bean的名称匹配,建议使用@Qualifier注解指定要装配的bean名称

注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法。

1.2 使用@Qualifier注解指定要装配的bean名称

目的:解决IoC容器中同类型Bean有多个装配哪一个的问题

@Service
public class StudentServiceImpl implements StudentService {

    //创建成员对象
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    @Autowired
    //@Qualifier:自动装配bean时按bean名称装配
    @Qualifier("studentDaoImpl")
    private StudentDao studentDao ;

    @Override
    public void save() {
        System.out.println("Service: 添加学生信息到数据库...");
        studentDao.save();
    }
}

注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用

1.3 使用@Value实现简单类型注入

@Repository
public class StudentDaoImpl implements StudentDao {

    //@Value:注入简单类型(无需提供set方法)
    @Value("${test.name}")
    private String name;
    @Override
    public void save() {
        System.out.println("DAO: name= "+name);
        System.out.println("DAO: 添加学生信息到数据库...");
    }
}

以上@Value注解中使用${test.name}从属性文件中读取test.name值,那么就需要在配置类或者配置文件中加载属性文件。

@Configuration
@ComponentScan("com.itheima")
//@PropertySource加载properties配置文件
@PropertySource("classpath:test.properties") //如果是多个属性文件,则使用{}数组
public class SpringConfig {
}

注意:@PropertySource中加载多文件请使用数组格式配置,不允许使用通配符*

2 注解开发管理第三方Bean【重点】

问题导入

思考:导入自己定义的配置类有几种方式?

【第零步】pom.xml添加数据库依赖

<!-- mysql 驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>
<!--druid包-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.18</version>
</dependency>

【第一步】单独定义配置类在config包下创建

package com.zbbmeta.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

public class JdbcConfig {
    //@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_druid");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

【第二步】将独立的配置类加入核心配置

方式1:@Import注解导入式

@Configuration // 指定这个类为配置类,替代application.xml
@ComponentScan("com.zbbmeta")//代替<context:component-scan base-package="com.zbbmeta" />
@PropertySource("classpath:test.properties") //如果是多个属性文件,则使用{}数组
@Import(JdbcConfig.class)  //加载JdbcConfig配置类
public class SpringConfig {


}

方式2:@ComponentScan扫描式

  • JdbcConfig类上添加注解
@Configuration
public class JdbcConfig {
    //@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_druid");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
  • SpringConfig配置不变
@Configuration // 指定这个类为配置类,替代application.xml
@ComponentScan("com.zbbmeta")//代替<context:component-scan base-package="com.zbbmeta" />
@PropertySource("classpath:test.properties") //如果是多个属性文件,则使用{}数组
//@Import(JdbcConfig.class)  //加载JdbcConfig配置类
public class SpringConfig {

}

3 注解开发为第三方Bean注入资源【重点】

问题导入

思考:配置类中如何注入简单类型数据,如何注入引用类型数据?

3.1 简单类型依赖注入

public class JdbcConfig {
    
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/spring_db")
    private String url;
    @Value("root")
    private String userName;
    @Value("root")
    private String password;
    
    //1.定义一个方法获得要管理的对象
    //2.@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}

说明:如果@Value()中使用了EL表达式读取properties属性文件中的内容,那么就需要加载properties属性文件。

3.2 引用类型依赖注入

//Spring会自动从IOC容器中根据类型找到StudentDao对象赋值给参数studentDao变量,如果没有就会报错。
    @Bean
    public DataSource dataSource(StudentDao studentDao){
        System.out.println("JdbcConfig  studentDao = " + studentDao);
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }

注意:引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

3.3 测试类

    @Test
    public void testDatasource() throws SQLException {

        //目标:从IOC容器中获取德鲁伊连接池对象
        //1.AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        //按类型获取bean
        DataSource dataSource = ac.getBean(DataSource.class);
        Connection connection = dataSource.getConnection();
        //3.打印对象
        System.out.println("连接池对象:"+dataSource);
        System.out.println("连接象地址:"+connection);
        //4.关闭容器
        ac.close();
    }

3.4 注解开发总结

标签:装配,Java,Spring,class,程序开发,public,Bean,注解,ds
From: https://blog.51cto.com/u_12023894/7012588

相关文章

  • 【JavaScript27】关于Function
    js中所有的函数都是通过Function构建的.在没有修改过原型链的情况下.以下等式是成立的.console.log(fn.proto.constructor===Function.prototype.constructor);console.log(fn.proto.constructor===Function);varfn=newFunction("console.log(123456);");//Funct......
  • 【JavaScript26】继承
    JS中实现继承,只需要改变函数的原型链即可示例functionCat(name){this.name=name;}Cat.prototype.eat_fish=function(fish){console.log(this.name,"在吃",fish);};functionBosiCat(name){this.name=name;}BosiCat.prototype.dance=functi......
  • 每日汇报 第七周第二天 JAVA复习&PTA
    今日学习:继续从网站中复习,PTA刷题时又复习了一下C++的vector用法和unordered_mapunordered_map是一个将key和value关联起来的容器,它可以高效的根据单个key值查找对应的value。key值应该是唯一的,key和value的数据类型可以不相同。unordered_map存储元素时是没有顺序的,......
  • 【JavaScript25】关于prototype
    老版本的js中是没有类的概念的.js如何构建一个对象的呢?在js中,每一个函数都可以作为构建一个对象的构造方法函数又可以被称为构造函数constructor构造器,构造方法functionPerson(name,age){//给当前对象(内存)进行初始化this.name=name;this.age......
  • Spring Cloud之Hystrix
    微服务架构中,服务数量大大增加,调用关系变得复杂。用户的一个请求,会放大为内部服务间的若干次调用,依赖实际上变多了。而一个服务的故障,沿着调用链传播,也可能造成难以预料的影响。更糟糕的是,在服务数量很多的时候,故障是无可避免的。不论单个服务可用性达到几个9,在服务数量N很大时,......
  • 《Java编程思想第四版》学习笔记07
    到底应该使用一个接口还是一个抽象类呢?若使用接口,我们可以同时获得抽象类以及接口的好处。所以假如想创建的基础类没有任何方法定义或者成员变量,那么无论如何都愿意使用接口,而不要选择抽象类。事实上,如果事先知道某种东西会成为基础类,那么第一个选择就是把它变成一个接口。只有在必......
  • springbatch remote partition
    SpringBatch远程分区demo*使用框架版本<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.han</groupId> <......
  • 不可错过!12个编写整洁Java代码的最佳实践方法
    在软件开发领域摸爬滚打了这些年之后,通过与各类开发者合作,审查他们所编写的代码所累积的经验,使飞哥对整洁代码的理解和认识有了本质的提升。引用《代码整洁之道》中的一段话,实际上,我们花在阅读代码上的时间远远超过编写代码的时间,这个比例甚至超过10比1。在我们致力于编写新代码的......
  • java springcloud 大文件分片上传处理
    ​ 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现。先说下要求:PC端全平台支持,要求支持Windows,Mac,Linux支持所有浏览器。支持文件批量上传支持文件夹上传,且要求在服务端保留层级结构。文件夹数量要求支持到10W......
  • java动态代理
    动态代理代理比较好理解,和现实生活中意思一样。就是我要干一件事情,可以通过代理人或代理平台进行完成,不需要直接和服务方接触。又或者计算机网络上说的代理。为什么叫动态代理?这里回到java程序上,是因为在运行时可以动态的创建接口的实现,通过java的反射进行实现。依赖三个关键类......