Java开发学习(十三)—-基于注解开发定义第三方bean及注解开发总结

在前面的博客中定义bean的时候都是在自己开发的类上面写个注解就完成了,但如果是第三方的类,这些类都是在jar包中,我们没有办法在类上面添加注解,这个时候该怎么办?

遇到上述问题,我们就需要有一种更加灵活的方式来定义bean,这种方式不能在原始代码上面书写注解,一样能定义bean,这就用到了一个全新的注解@Bean。

这个注解该如何使用呢?

一、环境准备

学习@Bean注解之前先来准备环境:

  • 创建一个Maven项目
  • pom.xml添加Spring的依赖
<dependencies>
 &#xA0; &#xA0;<dependency>
 &#xA0; &#xA0; &#xA0; &#xA0;<groupid>org.springframework</groupid>
 &#xA0; &#xA0; &#xA0; &#xA0;<artifactid>spring-context</artifactid>
 &#xA0; &#xA0; &#xA0; &#xA0;<version>5.2.10.RELEASE</version>
 &#xA0; &#xA0;</dependency>
</dependencies>
  • 添加一个配置类 SpringConfig
@Configuration
public class SpringConfig {
}
  • 添加BookDao、BookDaoImpl类
public interface BookDao {
 &#xA0; &#xA0;public void save();
}
@Repository
public class BookDaoImpl implements BookDao {
 &#xA0; &#xA0;public void save() {
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println("book dao save ..." );
 &#xA0;  }
}
  • 创建运行类App
public class App {
 &#xA0; &#xA0;public static void main(String[] args) {
 &#xA0; &#xA0; &#xA0; &#xA0;AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
 &#xA0;  }
}

最终创建好的项目结构如下:

Java开发学习(十三)----基于注解开发定义第三方bean及注解开发总结

二、注解开发管理第三方bean

在上述环境中完成对 Druid数据源的管理,具体的实现步骤为:

步骤1:导入对应的jar包

<dependency>
 &#xA0; &#xA0;<groupid>com.alibaba</groupid>
 &#xA0; &#xA0;<artifactid>druid</artifactid>
 &#xA0; &#xA0;<version>1.1.16</version>
</dependency>

步骤2:在配置类中添加一个方法

注意该方法的返回值就是要创建的Bean对象类型

@Configuration
public class SpringConfig {
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}

步骤3:在方法上添加 @Bean注解

@Bean注解的作用是将方法的返回值制作为Spring管理的一个bean对象

@Configuration
public class SpringConfig {
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}

注意:不能使用 DataSource ds = new DruidDataSource()

因为DataSource接口中没有对应的setter方法来设置属性。

步骤4:从IOC容器中获取对象并打印

public class App {
 &#xA0; &#xA0;public static void main(String[] args) {
 &#xA0; &#xA0; &#xA0; &#xA0;AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
 &#xA0; &#xA0; &#xA0; &#xA0;DataSource dataSource = ctx.getBean(DataSource.class);
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(dataSource);
 &#xA0;  }
}

至此使用@Bean来管理第三方bean的案例就已经完成。如果有多个bean要被Spring管理,直接在配置类中多些几个方法,方法上添加@Bean注解即可。

三、引入外部配置类

如果把所有的第三方bean都配置到Spring的配置类 SpringConfig中,虽然可以,但是不利于代码阅读和分类管理,所有我们就想能不能按照类别将这些bean配置到不同的配置类中?

对于数据源的bean,我们新建一个 JdbcConfig配置类,并把数据源配置到该类下。

public class JdbcConfig {
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}

现在的问题是,这个配置类如何能被Spring配置类加载到,并创建DataSource对象在IOC容器中?针对这个问题,有两个解决方案:

3.1 使用包扫描引入

步骤1:在Spring的配置类上添加包扫描
@Configuration
@ComponentScan("com.itheima.config")
public class SpringConfig {

}
步骤2:在JdbcConfig上添加配置注解

JdbcConfig类要放入到 com.itheima.config包下,需要被Spring的配置类扫描到即可

@Configuration
public class JdbcConfig {
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}
步骤3:运行程序

依然能获取到bean对象并打印控制台。这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类,所有这种方式不推荐使用。

3.2 使用 @Import引入

方案一实现起来有点小复杂,Spring早就想到了这一点,于是又给我们提供了第二种方案。

这种方案可以不用加 @Configuration注解,但是必须在Spring配置类上使用 @Import注解手动引入需要加载的配置类

步骤1:去除JdbcConfig类上的注解
public class JdbcConfig {
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}
步骤2:在Spring配置类中引入
@Configuration
//@ComponentScan("com.itheima.config")
@Import({JdbcConfig.class})
public class SpringConfig {

}

注意:

  • 扫描注解可以移除
  • @Import参数需要的是一个数组,可以引入多个配置类。
  • @Import注解在配置类中只能写一次,下面的方式是不允许的
@Configuration
//@ComponentScan("com.itheima.config")
@Import(JdbcConfig.class)
@Import(Xxx.class)
public class SpringConfig {

}
步骤3:运行程序

依然能获取到bean对象并打印控制台

知识点1:@Bean

名称@Bean 类型方法注解位置方法定义上方作用设置该方法的返回值作为spring管理的bean 属性value(默认):定义bean的id

知识点2:@Import

名称@Import 类型类注解位置类定义上方作用导入配置类属性value(默认):定义导入的配置类类名, 当配置类有多个时使用数组格式一次性导入多个配置类

四、注解开发实现为第三方bean注入资源

在使用@Bean创建bean对象的时候,如果方法在创建的过程中需要其他资源该怎么办?

这些资源会有两大类,分别是 &#x7B80;&#x5355;&#x6570;&#x636E;&#x7C7B;&#x578B;&#x5F15;&#x7528;&#x6570;&#x636E;&#x7C7B;&#x578B;

4.1 简单数据类型

4.1.1 需求分析

对于下面代码关于数据库的四要素不应该写死在代码中,应该是从properties配置文件中读取。如何来优化下面的代码?

public class JdbcConfig {
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}
4.1.2 注入简单数据类型步骤
步骤1:类中提供四个属性
public class JdbcConfig {
 &#xA0; &#xA0;private String driver;
 &#xA0; &#xA0;private String url;
 &#xA0; &#xA0;private String userName;
 &#xA0; &#xA0;private String password;
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}
步骤2:使用 @Value注解引入值
public class JdbcConfig {
 &#xA0; &#xA0;@Value("com.mysql.jdbc.Driver")
 &#xA0; &#xA0;private String driver;
 &#xA0; &#xA0;@Value("jdbc:mysql://localhost:3306/spring_db")
 &#xA0; &#xA0;private String url;
 &#xA0; &#xA0;@Value("root")
 &#xA0; &#xA0;private String userName;
 &#xA0; &#xA0;@Value("password")
 &#xA0; &#xA0;private String password;
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName(driver);
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl(url);
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername(userName);
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword(password);
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}
扩展

现在的数据库连接四要素还是写在代码中,需要做的是将这些内容提

取到jdbc.properties配置文件,具体实现步骤如下:

1.resources目录下添加jdbc.properties
2.配置文件中提供四个键值对分别是数据库的四要素
3.使用@PropertySource加载jdbc.properties配置文件
4.修改@Value注解属性的值,将其修改为 ${key},key就是键值对中的键的值

具体的实现这里就不实现了,可以参考前面的博客。

4.2 引用数据类型

4.2.1 需求分析

假设在构建DataSource对象的时候,需要用到BookDao对象,该如何把BookDao对象注入进方法内让其使用呢?

public class JdbcConfig {
    @Bean
 &#xA0; &#xA0;public DataSource dataSource(){
 &#xA0; &#xA0; &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setDriverClassName("com.mysql.jdbc.Driver");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setUsername("root");
 &#xA0; &#xA0; &#xA0; &#xA0;ds.setPassword("root");
 &#xA0; &#xA0; &#xA0; &#xA0;return ds;
 &#xA0;  }
}
4.2.2 注入引用数据类型步骤
步骤1:在SpringConfig中扫描BookDao

扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象

@Configuration
@ComponentScan("com.itheima.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}
步骤2:在JdbcConfig类的方法上添加参数
@Bean
public DataSource dataSource(BookDao bookDao){
 &#xA0; &#xA0;System.out.println(bookDao);
 &#xA0; &#xA0;DruidDataSource ds = new DruidDataSource();
 &#xA0; &#xA0;ds.setDriverClassName(driver);
 &#xA0; &#xA0;ds.setUrl(url);
 &#xA0; &#xA0;ds.setUsername(userName);
 &#xA0; &#xA0;ds.setPassword(password);
 &#xA0; &#xA0;return ds;
}

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

步骤3:运行程序

Java开发学习(十三)----基于注解开发定义第三方bean及注解开发总结

五、注解开发总结

在前面的博客中我们已经完成了XML配置和注解的开发实现,至于两者之间的差异,咱们放在一块去对比回顾下:

Java开发学习(十三)----基于注解开发定义第三方bean及注解开发总结

Original: https://www.cnblogs.com/xiaoyh/p/16324442.html
Author: |旧市拾荒|
Title: Java开发学习(十三)—-基于注解开发定义第三方bean及注解开发总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/538285/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Elasticsearch学习

    1 Elasticsearch 概述 Elaticsearch,简称为 ES,ES 是一个开源的高扩展的分布式全文搜索引擎,是整个 Elastic Stack 技术栈的核心。它可以…

    Java 2023年6月5日
    092
  • 记一次线上服务器301异常 httpclient的坑

    一、场景复现 营运车应用在登录过程中需要调用用户中心认证的接口来完成统一登录,因为云服务器升级对请求限制https only,在登录过程中出现系统异常(server error服务…

    Java 2023年6月13日
    085
  • .Net Core下DllImport使用方法及扩展

    引言​ 在有时候的开发过程中,我们会遇到需要调用系统的API,不巧的是.Net Core可能没办法为我们提供相关的调用方式。那需要如何才能解决这个问题呢?​ 这时候我们就可能会考虑…

    Java 2023年6月15日
    084
  • 安装jar包到本地maven仓库命令

    执行命令mvn install:install-file -DgroupId=net.neoremind -DartifactId=fountain-common -Dversio…

    Java 2023年6月13日
    096
  • 60行自己动手写LockSupport是什么体验?

    60行自己动手写LockSupport是什么体验? 前言 在JDK当中给我们提供的各种并发工具当中,比如 ReentrantLock等等工具的内部实现,经常会使用到一个工具,这个工…

    Java 2023年6月8日
    077
  • Makedown学习与使用

    +标题名字 +标题名字 …… +标题名字 6级标题,从1-6级为1-6个# 字体 Hello,worldHello,worldHello,worldHell…

    Java 2023年6月9日
    073
  • 面经:计网、OS

    同步、异步 1、同步:需要线程之间协同操作,才能完成一件事。于是就会有 “阻塞” 状态 2、异步:线程之间不需要互相等待,将事情丢进去,处理完给个结果就行 …

    Java 2023年6月7日
    074
  • Java开发笔记(一百四十一)JavaFX的列表与表格

    下拉框只有在单击时才会弹出所有选项的下拉列表,这固然节省了有限的界面空间,但有时候又需要把所有选项都固定展示到窗口上。像这种平铺的列表控件,Swing给出的控件名称是ListBox…

    Java 2023年6月6日
    078
  • 分布式锁

    分布式锁 本文整理自黑马程序员相关资料 问题的引入 在平时单服务的情况下,我们使用互斥锁可以保证同一时刻只有一个线程执行自己的业务。原理是,在JVM内部维护了一个锁监视器,锁监视器…

    Java 2023年6月8日
    065
  • 线程池

    1、池化技术(思想) (1)池化技术:程序运行的本质->占用系统的资源,优化资源的使用便是池化技术 (2)简单理解:实现准备好一些资源,有人要用,就来这个池拿,用完放回即可。…

    Java 2023年6月5日
    064
  • Node.js下载安装与配置(windows)

    一、Node.js下载 官网下载地址:下载 | Node.js 中文网 (nodejs.cn) 以Windows64位安装版为例,点击”Windows 安装包(.msi…

    Java 2023年6月8日
    046
  • 如何搭建一个WEB服务器项目(一)—— 开篇 ,搭建SSH整合框架

    使用Intellij IDEA2019创建SSH(Spring+SpringMVC+Hibernate+Maven整合)项目 观前提示:本系列文章有关服务器以及后端程序这些概念,我…

    Java 2023年6月8日
    094
  • axios的封装

    Vue中axios的封装 request.js请求封装、 import axios from ‘axios’ import { getToken } from ‘@/utils’ …

    Java 2023年6月5日
    081
  • Spring Boot:使用Rabbit MQ消息队列

    综合概述 消息队列 消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列…

    Java 2023年5月30日
    071
  • Windows下 RabbitMQ的安装和配置

    简介 RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放…

    Java 2023年6月5日
    0101
  • 32位Win7下安装与配置PHP环境(一)

    运行PHP网站,主要需要安装、配置三个软件,Apache、PHP和MySQL。如果需要编辑调试PHP程序,还要安装一个编辑调试软件。一、 ApacheApache是和IIS类似的一…

    Java 2023年5月29日
    063
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球