Spring(2)Spring从零到入门 - Spring注解开发(以IoC/DI为核心)
文章目录
3 Spring之IOC/DI注解开发
3.1 注解开发定义bean
3.1.1 基础环境
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookDao" class="com.baidu.dao.impl.BookDaoImpl"/>
</beans>
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService {
public void save() {
System.out.println("book service save ...");
}
}
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
3.1.2 注解开发定义bean
步骤1:删除原XML配置
将配置文件中的<bean>
标签删除掉
<bean id="bookDao" class="com.baidu.dao.impl.BookDaoImpl"/>
步骤2:Dao上添加注解
在BookDaoImpl类上添加@Component
注解
@Component("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
注意:@Component注解不可以添加在接口上,因为接口是无法创建对象的。
XML与注解配置的对应关系: 一个注解类就相当于一个Bean
![1629990315619](https://i-blog.csdnimg.cn/blog_migrate/990925cfc78b79a442ec16d577fc19de.png)
步骤3: 配置Spring的注解包扫描
为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:component-scan base-package="com.baidu"/>
</beans>
说明:
component-scan
- component:组件,Spring将管理的bean视作自己的一个组件
- scan:扫描
base-package指定Spring框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。
- 包路径越多[如:com.baidu.dao.impl],扫描的范围越小速度越快
- 包路径越少[如:com.baidu],扫描的范围越大速度越慢
- 一般扫描到项目的组织名称即Maven的groupId下[如:com.baidu]即可。
步骤4:运行程序
运行App
类查看打印结果
步骤5:Service上添加注解
在BookServiceImpl类上也添加@Component
交给Spring框架管理
@Component
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
步骤6:运行程序
在App类中,从IOC容器中获取BookServiceImpl对应的bean对象,打印
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
//按类型获取bean
BookService bookService = ctx.getBean(BookService.class);
System.out.println(bookService);
}
}
打印观察结果,两个bean对象都已经打印到控制台
说明:
-
BookServiceImpl类没有起名称,所以在App中是按照类型来获取bean对象
-
@Component注解如果不起名称,会有一个默认值就是
当前类名首字母小写
,所以也可以按照名称获取,如BookService bookService = (BookService)ctx.getBean("bookServiceImpl"); System.out.println(bookService);
对于@Component注解,还衍生出了其他三个注解**@Controller、@Service、@Repository**
通过查看源码会发现:
这三个注解和@Component注解的作用是一样的
目的是方便我们后期在编写类的时候能很好的区分出这个类是属于表现层、业务层还是数据层的类。
知识点: @Component等注解
名称 | @Component/@Controller/@Service/@Repository |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类为spring管理的bean |
属性 | value(默认):定义bean的id |
3.2 纯注解开发
将配置文件applicationContext.xml删除掉,使用类来替换
步骤1:创建配置类
创建一个配置类SpringConfig
public class SpringConfig {
}
步骤2:标识该类为配置类
在配置类上添加@Configuration
注解,将其标识为一个配置类,替换applicationContext.xml
@Configuration
public class SpringConfig {
}
步骤3:用注解替换包扫描配置
在配置类上添加包扫描注解@ComponentScan
替换<context:component-scan base-package=""/>
@Configuration
@ComponentScan("com.baidu")
public class SpringConfig {
}
步骤4:创建运行类并执行
创建一个新的运行类AppForAnnotation
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
public class AppForAnnotation {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
BookService bookService = ctx.getBean(BookService.class);
System.out.println(bookService);
}
}
运行AppForAnnotation,可以看到两个对象依然被获取成功
纯注解开发,主要内容包括:
-
Java类替换Spring核心配置文件
-
**@Configuration**注解用于设定当前类为配置类
-
@ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式<
@ComponentScan({com.baidu.service","com.baidu.dao"})
-
读取Spring核心配置文件初始化容器对象切换为**读取Java配置类初始化容器对象**
//加载配置文件初始化容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//加载配置类初始化容器 ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
知识点1:@Configuration
名称 | @Configuration |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类为spring配置类 |
属性 | value(默认):定义bean的id |
知识点2:@ComponentScan
名称 | @ComponentScan |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置spring配置类扫描路径,用于加载使用注解格式定义的bean |
属性 | value(默认):扫描路径,此路径可以逐层向下扫描 |
小结:
- 记住@Component、@Controller、@Service、@Repository这四个注解
- applicationContext.xml中
<context:component-san/>
的作用是指定扫描包路径,注解为@ComponentScan - @Configuration标识该类为配置类,使用类替换applicationContext.xml文件
- ClassPathXmlApplicationContext是加载XML配置文件
- AnnotationConfigApplicationContext是加载配置类
3.3 注解开发bean作用范围与生命周期管理
基础环境
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
@Configuration
@ComponentScan("com.baidu")
public class SpringConfig {
}
public interface BookDao {
public void save();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao1 = ctx.getBean(BookDao.class);
BookDao bookDao2 = ctx.getBean(BookDao.class);
System.out.println(bookDao1);
System.out.println(bookDao2);
}
}
3.3.1 bean的作用范围
(1)先运行App类,在控制台打印两个一摸一样的地址,说明默认情况下bean是单例
(2)类上添加@scope注解,使之变成非单例的
@Repository
//@Scope设置bean的作用范围
@Scope("prototype")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
知识点:@Scope
名称 | @Scope |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类创建对象的作用范围 可用于设置创建出的bean是否为单例对象 |
属性 | value(默认):定义bean作用范围, 默认值singleton(单例),可选值prototype(非单例) |
3.3.2 bean的生命周期
对方法进行标识,初始化方法,销毁方法
添加@PostConstruct和@PreDestroy注解
JDK9以后jdk中的javax.annotation包被移除了,这两个注解刚好就在这个包中,所以添加下面依赖
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
@PostConstruct //在构造方法之后执行,替换 init-method
public void init() {
System.out.println("init ...");
}
@PreDestroy //在销毁方法之前执行,替换 destroy-method
public void destroy() {
System.out.println("destroy ...");
}
}
同样,destroy只有在容器关闭的时候,才会执行。
回顾:关闭有两种方法,close关闭和注册钩子关闭。
注意:
非单例模式下容器并没有调用destory指定方法,多例模式下spring不负责销毁
知识点1:@PostConstruct
名称 | @PostConstruct |
---|---|
类型 | 方法注解 |
位置 | 方法上 |
作用 | 设置该方法为初始化方法 |
属性 | 无 |
知识点2:@PreDestroy
名称 | @PreDestroy |
---|---|
类型 | 方法注解 |
位置 | 方法上 |
作用 | 设置该方法为销毁方法 |
属性 | 无 |
小结
注解与配置文件的对应关系:
3.4 注解开发依赖注入
Spring没有提供构造函数注入、setter注入对应的注解,只提供了自动装配的注解实现
基础环境
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
@Configuration
@ComponentScan("com.baidu")
public class SpringConfig {
}
public interface BookDao {
public void save();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
public interface BookService {
public void save();
}
@Service
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookService bookService = ctx.getBean(BookService.class);
bookService.save();
}
}
不能实现依赖注入,报错:
原因:BookServiceImpl中的BookDao的属性,没有成功注入,(即使有相关setter函数也不起作用)为null
3.4.1 注解实现按照类型注入
在BookServiceImpl类的bookDao属性上添加@Autowired
注解
@Autowired可以写在属性上,也可也写在setter方法上,推荐**写在属性上并将setter方法删除掉**
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
// public void setBookDao(BookDao bookDao) {
// this.bookDao = bookDao;
// }
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
为什么setter方法可以删除呢?
- 自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值
- 普通反射只能获取public修饰的内容
- 暴力反射除了获取public修饰的内容还可以获取private修改的内容
- 所以此处无需提供setter方法
如果同一个类型有多个实现类,那么会报错。此时无法区分到底要注入哪一个对象
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
@Repository
public class BookDaoImpl2 implements BookDao {
public void save() {
System.out.println("book dao save ...2");
}
}
解决办法:按照名称注入。
3.4.2 注解实现按照名称注入
3.4.2.1 在原注解上备注该bean对象名称
给这两个Dao,起两个不一样的名字
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
@Repository("bookDao2")
public class BookDaoImpl2 implements BookDao {
public void save() {
System.out.println("book dao save ...2" );
}
}
此时可以注入成功。
注意,此时IOC容器中同类的Bean仍有多个;@Autowired默认按照类型自动装配,如果IOC容器中同类的Bean找到多个,就按照变量名和Bean的名称匹配。因为变量名叫bookDao
而容器中也有一个bookDao
,所以可以成功注入。
例如出现下面这种情况,就不能成功完成注入:
报错:NoUniqueBeanDefinitionException
3.4.2.2 @Qualifier指定注入哪个名称的bean对象
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao1")
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
@Qualifier注解后的值就是需要注入的bean的名称。
注意:@Qualifier不能独立使用,必须和@Autowired一起使用
3.4.3 简单数据类型注入
简单数据类型:基本数据类型、字符串类型
- @Value注解,将值写入注解的参数中
- 注意数据格式要匹配,如将"abc"注入给int值,这样程序就会报错。
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("baidu")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
上述内容和直接赋值等效。
3.4.4 注解读取properties配置文件
@Value一般会被用在从properties配置文件中读取内容进行使用
步骤1:resource下准备properties文件
jdbc.properties
name=baidu888
步骤2: 使用注解加载properties配置文件
在配置类上添加@PropertySource
注解
@Configuration
@ComponentScan("com.baidu")
@PropertySource("jdbc.properties")
public class SpringConfig {
}
步骤3:使用@Value读取配置文件中的内容
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("${name}")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
步骤4:运行程序
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookService bookService = ctx.getBean(BookService.class);
bookService.save();
}
}
注意:
-
如果读取的properties配置文件有多个,可以使用
@PropertySource
的属性来指定多个@PropertySource({"jdbc.properties","xxx.properties"})
-
@PropertySource
注解属性中不支持使用通配符*
,运行会报错@PropertySource({"*.properties"})
-
@PropertySource
注解属性中可以把classpath:
加上,代表从当前项目的根路径找文件@PropertySource({"classpath:jdbc.properties"})
知识点1:@Autowired
名称 | @Autowired |
---|---|
类型 | 属性注解 或 方法注解(了解) 或 方法形参注解(了解) |
位置 | 属性定义上方 或 标准set方法上方 或 类set方法上方 或 方法形参前面 |
作用 | 为引用类型属性设置值 |
属性 | required:true/false,定义该属性是否允许为null |
知识点2:@Qualifier
名称 | @Qualifier |
---|---|
类型 | 属性注解 或 方法注解(了解) |
位置 | 属性定义上方 或 标准set方法上方 或 类set方法上方 |
作用 | 为引用类型属性指定注入的beanId |
属性 | value(默认):设置注入的beanId |
知识点3:@Value
名称 | @Value |
---|---|
类型 | 属性注解 或 方法注解(了解) |
位置 | 属性定义上方 或 标准set方法上方 或 类set方法上方 |
作用 | 为 基本数据类型 或 字符串类型 属性设置值 |
属性 | value(默认):要注入的属性值 |
知识点4:@PropertySource
名称 | @PropertySource |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 加载properties文件中的属性值 |
属性 | value(默认):设置加载的properties文件对应的文件名或文件名组成的数组 |
3.5 IOC/DI注解开发管理第三方bean
3.5.1 注解开发管理第三方bean
对于别人开发的第三方代码,不能在原始代码上面书写注解,要怎样为其属性赋值
环境准备:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
@Configuration
public class SpringConfig {
}
public interface BookDao {
public void save();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
}
}
以
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要被Spring管理,直接在配置类中多些几个方法,方法上添加@Bean注解即可。
3.5.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容器中?
① 使用包扫描引入
步骤1:在Spring的配置类上添加包扫描
@Configuration
@ComponentScan("com.baidu.config")
public class SpringConfig {
}
步骤2:在JdbcConfig上添加配置注解
JdbcConfig类要放入到com.baidu.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;
}
}
这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类,不推荐使用。
② 使用@Import
引入
可以不用加@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.baidu.config")
@Import({JdbcConfig.class})
public class SpringConfig {
}
注意:
-
扫描注解可以移除
回顾 扫描注解的作用:为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描
-
@Import参数需要的是一个数组,可以引入多个配置类。
-
@Import注解在配置类中只能写一次,下面的方式是不允许的
@Configuration //@ComponentScan("com.baidu.config") @Import(JdbcConfig.class) @Import(Xxx.class) public class SpringConfig { }
步骤3:运行程序
依然能获取到bean对象并打印控制台
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);
}
}
知识点1:@Bean
名称 | @Bean |
---|---|
类型 | 方法注解 |
位置 | 方法定义上方 |
作用 | 设置该方法的返回值作为spring管理的bean |
属性 | value(默认):定义bean的id |
知识点2:@Import
名称 | @Import |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 导入配置类 |
属性 | value(默认):定义导入的配置类类名, 当配置类有多个时使用数组格式一次性导入多个配置类 |
3.5.3 注解开发实现为第三方bean注入资源
在使用@Bean创建bean对象的时候,如果方法在创建的过程中需要其他资源该怎么办?
这些资源会有两大类,分别是简单数据类型
和引用数据类型
。
3.5.3.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;
}
}
步骤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.配置文件中提供四个键值对分别是数据库的四要素
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db jdbc.username=root jdbc.password=1234
3.使用@PropertySource加载jdbc.properties配置文件
@Configuration @ComponentScan("com.baidu") //@Import:导入配置信息 @Import({JdbcConfig.class}) @PropertySource("classpath:jdbc.properties") //或者 @PropertySource("/jdbc.properties") //写@PropertySource("jdbc.properties")识别不到建立在resource下的jdbc.properties文件 public class SpringConfig { }
4.修改@Value注解属性的值,将其修改为
${key}
,key就是键值对中的键的值public class JdbcConfig { //1.定义一个方法获得要管理的对象 @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String userName; @Value("${jdbc.password}") private String password; //2.添加@Bean,表示当前方法的返回值是一个bean //@Bean修饰的方法,形参根据类型自动装配 @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; } }
3.5.3.2 引用数据类型
假设在构建DataSource对象的时候,需要用到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;
}
}
步骤1:在SpringConfig中扫描BookDao
扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象
@Configuration
@ComponentScan("com.baidu.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}
注意此时的BookDaoImpl类上一定要有注入的注解
@Repository
@Repository public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }
步骤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:运行程序
3.6 注解开发总结
XML配置和注解的开发的对比
3.7 Spring归纳
Spring有一个容器,叫做IoC容器,里面保存bean。
setUrl(“jdbc:mysql://localhost:3306/spring_db”);
ds.setUsername(“root”);
ds.setPassword(“root”);
return ds;
}
}
**步骤1:在SpringConfig中扫描BookDao**
扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象
```java
@Configuration
@ComponentScan("com.baidu.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}
注意此时的BookDaoImpl类上一定要有注入的注解
@Repository
@Repository public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }
步骤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:运行程序
[外链图片转存中…(img-F3u96aHk-1703147391576)]
3.6 注解开发总结
XML配置和注解的开发的对比
[外链图片转存中…(img-3I3xHU9F-1703147391576)]
3.7 Spring归纳
Spring有一个容器,叫做IoC容器,里面保存bean。
在进行企业级开发的时候,其实除了将自己写的类让Spring管理之外,还有一部分重要的工作就是使用第三方的技术。