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

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

这个注解该如何使用呢?

一、环境准备

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

  • 创建一个Maven项目

  • pom.xml添加Spring的依赖

    <dependencies>
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
           <version>5.2.10.RELEASE</version>
       </dependency>
    </dependencies>
  • 添加一个配置类SpringConfig

    @Configuration
    public class SpringConfig {
    }
  • 添加BookDao、BookDaoImpl类

    public interface BookDao {
       public void save();
    }
    @Repository
    public class BookDaoImpl implements BookDao {
       public void save() {
           System.out.println("book dao save ..." );
      }
    }
  • 创建运行类App

    public class App {
       public static void main(String[] args) {
           AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
      }
    }

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

    

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

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

步骤1:导入对应的jar包

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.1.16</version>
</dependency>

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

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

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

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

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

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

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

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

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

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

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

三、引入外部配置类

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

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

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

现在的问题是,这个配置类如何能被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
   public DataSource dataSource(){
       DruidDataSource ds = new DruidDataSource();
       ds.setDriverClassName("com.mysql.jdbc.Driver");
       ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
       ds.setUsername("root");
       ds.setPassword("root");
       return ds;
  }
}
步骤3:运行程序

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

3.2 使用@Import引入

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

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

步骤1:去除JdbcConfig类上的注解
public class JdbcConfig {
@Bean
   public DataSource dataSource(){
       DruidDataSource ds = new DruidDataSource();
       ds.setDriverClassName("com.mysql.jdbc.Driver");
       ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
       ds.setUsername("root");
       ds.setPassword("root");
       return ds;
  }
}
步骤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对象的时候,如果方法在创建的过程中需要其他资源该怎么办?

这些资源会有两大类,分别是简单数据类型引用数据类型

4.1 简单数据类型

4.1.1 需求分析

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

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

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

取到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
   public DataSource dataSource(){
       DruidDataSource ds = new DruidDataSource();
       ds.setDriverClassName("com.mysql.jdbc.Driver");
       ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
       ds.setUsername("root");
       ds.setPassword("root");
       return ds;
  }
}
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){
   System.out.println(bookDao);
   DruidDataSource ds = new DruidDataSource();
   ds.setDriverClassName(driver);
   ds.setUrl(url);
   ds.setUsername(userName);
   ds.setPassword(password);
   return ds;
}

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

步骤3:运行程序

五、注解开发总结

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

Java开发学习(十三)----基于注解开发定义第三方bean及注解开发总结的更多相关文章

  1. Java开发学习(十)----基于注解开发定义bean 已完成

    一.环境准备 先来准备下环境: 创建一个Maven项目 pom.xml添加Spring的依赖 <dependencies>    <dependency>        < ...

  2. Java开发学习(十一)----基于注解开发bean作用范围与生命周期管理

    一.注解开发bean作用范围与生命周期管理 前面使用注解已经完成了bean的管理,接下来将通过配置实现的内容都换成对应的注解实现,包含两部分内容:bean作用范围和bean生命周期. 1.1 环境准备 ...

  3. Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发

    一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...

  4. 【Java EE 学习 83 下】【SpringMVC】【使用注解替代已过时的API】【SpringMVC、Hibernate整合】

    一.SpringMVC中注解的使用 1.为什么要使用注解 之前曾经提到过的三种控制器在spring3.0中都已经被明确标记为过时了,spring3.0推荐使用注解的方式替代三种控制器,实际上使用注解的 ...

  5. Android开发学习笔记--给一个按钮定义事件

    学习Android的第一天,了解了各种布局,然后自己动手画出了一个按钮,然后给按钮定义了一个事件是弹出一条消息显示“我成功了!”字样,具体过程如下: 1.修改布局文件activity_main.xml ...

  6. 接单,开发,学习神器--基于SpringSecurity的后台权限管理系统

    基于SpringSecurity--码仔后台管理系统 1.技术选项 >- 核心框架 SpringBoot >- 权限框架 SpringSecurity >- 模板引擎 Thymele ...

  7. vue移动音乐app开发学习(三):轮播图组件的开发

    本系列文章是为了记录学习中的知识点,便于后期自己观看.如果有需要的同学请登录慕课网,找到Vue 2.0 高级实战-开发移动端音乐WebApp进行观看,传送门. 完成后的页面状态以及项目结构如下: 一: ...

  8. java web 学习十三(使用session防止表单重复提交)

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...

  9. JAVA多线程学习十三 - 同步工具CyclicBarrier与CountDownLatch

    一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序 ...

随机推荐

  1. Python技法:用re模块实现简易tokenizer

    一个简单的tokenizer 分词(tokenization)任务是Python字符串处理中最为常见任务了.我们这里讲解用正则表达式构建简单的表达式分词器(tokenizer),它能够将表达式字符串从 ...

  2. 工程师姓什么很重要!别再叫我“X工”!!!

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 工程师之间都是这么互相打招呼的-- "高工,你设计图通过了么?" &quo ...

  3. 浅谈 UNIX、Linux、ios、android 他们之间的关系

    开源Linux 一个执着于技术的公众号 Unix, 简化形成了Linux,Linux则是Android的内核,而苹果则是使用unix系统作为ios和macos的内核. 几个系统出现的时间 UNIX系统 ...

  4. 1903021121—刘明伟—Java第六周作业—java类

    项目   内容 课程班级博客链接  19信计班(本) 作业要求链接 第6周作业 扩展阅读 java面向对象的概念和定义 作业要求 每道题要有题目,代码,截图(只截运行结果). 题目1: 一个Phone ...

  5. 好客租房31-事件绑定this指向(bind)

    事件this指向bind 利用ES5中bind方法 将事件处理程序中的this和组件实例绑定在一起 //导入react     import React from 'react'           ...

  6. ElasticSearch7.3学习(二十七)----聚合概念(bucket和metric)及其示例

    一.两个核心概念:bucket和metric 1.1 bucket 有如下数据 city name  北京 张三  北京 李四 天津 王五 天津 赵六 天津 王麻子 划分出来两个bucket,一个是北 ...

  7. 520表白小程序设计Python代码详解(PyQt5界面,B站动漫风)

    摘要:介绍一个动漫风的表白小程序,界面使用Python以及PyQt实现,界面样式经过多次美化调整,使得整体清新美观.本文详细介绍代码设计和实现过程,不仅是居家表白必备,而且适合新入门的朋友学习界面设计 ...

  8. 搭建NTP时间服务器~使用NTP同步时间~构建主机间时间自动同步关系

    NTP是一个时间服务器,同时它也是一个时间客户端. 我们可以使用它构建主机与主机之间的时间自动同步环境,保证所有服务器时间一致性. 常用的公共NTP时间服务器有: cn.ntp.org.cn 中国 n ...

  9. Python Django 功能模块

    Python Django模块 Django模块,是针对有django基础,对django功能进行模块化,方便下次使用. 一.注册模块 该注册采用邮箱验证,注册成功后会发送激活链接到邮箱. 邮箱验证参 ...

  10. MTK 虚拟 sensor bring up (pick up) sensor2.0

    pick up bring up sensor2.0 1.SCP侧的配置 (1) 放置驱动pickup.c (2) 添加底层驱动文件编译开关 (3) 加入编译文件 (4) 增加数据上报方式 (5)修改 ...