1. 注解开发管理第三方 bean
在上述环境中完成对Druid
数据源的管理,具体的实现步骤为:
步骤 1:导入对应的 jar 包
代码语言:javascript复制<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
步骤 2:在配置类中添加一个方法
注意该方法的返回值就是要创建的 Bean 对象类型
代码语言:javascript复制@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 对象
代码语言:javascript复制@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 容器中获取对象并打印
代码语言:javascript复制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 注解即可。
2. 引入外部配置类
如果把所有的第三方 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 容器中?
针对这个问题,有两个解决方案:
2.1 使用包扫描引入
步骤 1:在 Spring 的配置类上添加包扫描
代码语言:javascript复制@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 对象并打印控制台。
这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类,所有这种方式不推荐使用。
2.2 使用@Import
引入
方案一实现起来有点小复杂,Spring 早就想到了这一点,于是又给我们提供了第二种方案。
这种方案可以不用加@Configuration
注解,但是必须在 Spring 配置类上使用@Import
注解手动引入需要加载的配置类
步骤 1:去除 JdbcConfig 类上的注解
代码语言:javascript复制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 配置类中引入
代码语言:javascript复制@Configuration
//@ComponentScan("com.itheima.config")
@Import({JdbcConfig.class})
public class SpringConfig {
}
注意:
扫描注解可以移除
@Import 参数需要的是一个数组,可以引入多个配置类。
@Import 注解在配置类中只能写一次,下面的方式是不允许的
代码语言:javascript复制@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(默认):定义导入的配置类类名, 当配置类有多个时使用数组格式一次性导入多个配置类 |
3. 注解开发实现为第三方 bean 注入资源
在使用@Bean 创建 bean 对象的时候,如果方法在创建的过程中需要其他资源该怎么办?
这些资源会有两大类,分别是简单数据类型
和引用数据类型
。
3.1 简单数据类型
3.1.2 需求分析
对于下面代码关于数据库的四要素不应该写死在代码中,应该是从 properties 配置文件中读取。如何来优化下面的代码?
代码语言:javascript复制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.1.2 注入简单数据类型步骤
步骤 1:类中提供四个属性
代码语言:javascript复制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
注解引入值
代码语言:javascript复制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 就是键值对中的键的值
具体的实现就交由大家自行实现下。
3.2 引用数据类型
3.2.1 需求分析
假设在构建 DataSource 对象的时候,需要用到 BookDao 对象,该如何把 BookDao 对象注入进方法内让其使用呢?
代码语言:javascript复制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.2.2 注入引用数据类型步骤
步骤 1:在 SpringConfig 中扫描 BookDao
扫描的目的是让 Spring 能管理到 BookDao,也就是说要让 IOC 容器中有一个 bookDao 对象
代码语言:javascript复制@Configuration
@ComponentScan("com.itheima.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}
步骤 2:在 JdbcConfig 类的方法上添加参数
代码语言:javascript复制@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 定义方法设置形参即可,容器会根据类型自动装配对象。