Spring07——IOC/DI注解开发管理第三方bean(@Bean注解)、注解开发实现为第三方bean注入资源(简单数据类型/引用数据类型)

23-IOC/DI注解开发管理第三方bean

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

遇到上述问题,我们就需要有一种更加灵活的方式来定义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数据源的管理,具体的实现步骤为

  • 步骤一:导入对应的jar包
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>
  • 步骤二:在配置类中添加一个方法
    注意该方法的返回值就是要创建的Bean对象类型
@Configuration
public class SpringConfig {
    //定义要管理的对象
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

步骤三:在方法上添加@Bean注解
@Bean注解的作用是将方法的返回值作为一个Spring管理的bean对象

@Configuration
public class SpringConfig {
    //定义要管理的对象
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
  • 步骤四:从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类中
那现在又有了一个新问题,这个配置类如何能被Spring配置类加载到,并创建DataSource对象在IOC容器中?
针对这个问题,有两个解决方案,接着往下看

使用包扫描引入

  • 步骤一:在Spring的配置类上添加包扫描@ComponentScan
    注意要将JdbcConfig类放在包扫描的地址下
@Configuration
@ComponentScan("com.yolo.config")
public class SpringConfig {
}
  • 步骤二:在JdbcConfig上添加@Configuration注解
    JdbcConfig类要放入到com.blog.config包下,需要被Spring的配置类扫描到即可
@Configuration
public class JdbcConfig {
    //定义要管理的对象
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
  • 步骤三:运行程序
    仍然可以获取到bean对象并输出到控制台
    这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类(因为把包下的所有配置类都扫描了),所有这种方式不推荐使用。

使用@Import引入(推荐)

方案一实现起来有点小复杂,Spring早就想到了这一点,于是又给我们提供了第二种方案。
这种方案可以不用加@Configuration注解,但是必须在Spring配置类上使用@Import注解手动引入需要加载的配置类

  • 步骤一:去除JdbcConfig类上的注解
public class JdbcConfig {
    //定义要管理的对象
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
  • 步骤二:在Spring配置类中引入
@Configuration
//@ComponentScan("com.yolo.config")
@Import(JdbcConfig.class)
public class SpringConfig {
}

注意:
扫描注解可以移除
@Import 参数需要的是一个数组,可以引入多个配置类。
@Import注解在配置类中只能写一次

  • 步骤三:运行程序
    依然能获取到bean对象并打印控制台
    在这里插入图片描述
    知识点1:
    @Bean注解
    在这里插入图片描述
    知识点2:
    @Import注解
    在这里插入图片描述

24-注解开发实现为第三方bean注入资源

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

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

简单数据类型(成员变量)

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

public class JdbcConfig {
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring_db");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }
}
  • 步骤一:提供对应的四个属性
public class JdbcConfig {

    private String driver;
    private String url;
    private String username;
    private String password;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}
  • 步骤二:使用@Value注解
public class JdbcConfig {
    @Value("com.mysql.cj.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;

    //定义要管理的对象
    @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. 配置文件中提供四个键值对分别是数据库的四要素
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db
jdbc.username=root
jdbc.password=root.
  1. 输出结果如下
    在这里插入图片描述

引用数据类型(方法形参)

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

  • 步骤一:在SpringConfig中扫描BookDao
    扫描的目的是让Spring能管理到BookDao,也就是要让IOC容器中有一个BookDao对象
@Configuration
@ComponentScan("com.yolo.dao")
@Import(JdbcConfig.class)
public class SpringConfig {
}
  • 步骤二:在JdbcConfig类的方法上添加参数
    引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象。
@Bean
//    public DataSource dataSource()
    public DataSource dataSource(BookDao bookDao) {
        System.out.println(bookDao);
        bookDao.save();
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
  • 步骤三:运行程序
    结果如下,说明bookDao已经成功注入
    在这里插入图片描述

问:为什么只给一个形参就能获取到BookDao的bean对象?
答:自动装配。因为dataSource(BookDao bookDao)加了@Bean注解,程序检测到了dataSource(BookDao bookDao)这个方法是在做第三方bean或者是要配置一个bean,程序就认为它要给你提供形参,于是程序就在容器中找BookDao这个类型的bean,又因为BookDao的实现类加了@Repository注解,交给了Spring管理,所以能被识别到

25-注解开发总结

XML配置&注解配置

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值