Spring框架——使用注解实现Spring IOC

完全使用注解实现 IOC

​ 通过使用注解的方式,可以更方便的将我们自己创建的对象放入到 Spring bean 容器中,我们这里介绍使用纯注解的方式实现 IOC,并且主要介绍替代.xml文件配置的过程,虽然这种方式对于包装好的对象使用起来有些麻烦

准备

​ 首先我们需要准备一个.java的配置文件,用于取代bean.xml,我们将它建在com的父目录java中的config包下,取名为SpringConfiguration.java

思路

​ 既然说是取代,那这个类就要通过注解的方式,实现原本使用bean.xml配置 IOC 时的全部功能,我们先来看看之前使用注解和bean.xml结合配置 IOC 时的bean.xml是如何编写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.lmh"/>

<!-- 配置 QueryRunner 对象 -->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<constructor-arg name="ds" ref="dataSource"/>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?useSSL=false&amp;serverTimezone=UTC"/>
<property name="user" value="root"/>
<property name="password" value="lmh12358"/>
</bean>
</beans>

​ 下面,我们就根据 xml 文件所提供的功能,一个一个转化为注解实现

定义配置类(@Configuration)

​ 配置类config.SpringConfiguration.java我们已经创建好了,我们需要使用@Configuration来说明它是一个配置类如下:

1
2
3
4
@Configuration
public class SpringConfiguration {

}

指定注解存在的位置(@ComponentScan)

​ 随后,在bean.xml中有<context:component-scan base-package="com.lmh"/>这样一句话,它是说明在我们的项目中需要被扫描的使用注解的位置,我们在配置类中使用@ComponentScans注解实现这一功能

@ComponentScans注解用来指定 Spring 在创建容器所扫描的包,它里边需要使用@ComponentScan注解来指定包名,使用方法如下:

1
2
3
@ComponentScans(
@ComponentScan(basePackages = {"com.lmh", ...})
)

​ 通过这种方式可以指定需要扫描的包名,basePackages是一个数组,可以包含多个包名

使用注解将外部类放入容器(@Bean)

​ 以上的功能只能将我们自己的对象存入到 Spring 容器中,那如果是像QueryRunner这样的对象呢

​ 这是需要使用@Bean注解,@Bean注解用来修饰一个方法,可以把当前方法的返回值作为 bean 对象存入 Spring 的 IOC 容器中,name属性即为该 bean 的id,并且我们可以使用@Scope等注解来修饰它,使用如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Bean(name = "runner")
@Scope("prototype")
public QueryRunner createQueryRunner(DataSource dataSource) {
return new QueryRunner(dataSource);
}

@Bean(name = "dataSource")
public DataSource createDataSource() throws PropertyVetoException {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
return ds;
}

​ 我们可以看到,QueryRunner对象是需要使用DataSource类型的对象作为参数来创建的,这是就需要为这个 bean 注入DataSource dataSource,此时我们只需要定义一个id和参数名相同的bean即可,即使用注解配置方法时,如果方法有参数,Spring 框架会去容器中查找有没有可用的 bean,查找方式和 AutoWired 相同

其他一些常用注解

@Import

@Import注解用来定义子配置文件,假设我们要在JdbcConfig.java中配置 JDBC 连接信息,就可以通过在父配置类中使用@Import注解:

1
2
3
@Import(value = {
JdbcConfig.class
})

@PropertySources、@Value

@PropertySources注解用来指定.properties的配置文件,@Value用来调用配置文件中的值,通过这两个注解,我们可以调用配置文件的信息,例如将 JDBC 连接包装在配置文件中我们可这样使用

​ 配置文件:

1
2
3
4
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=lmh12358

​ JdbcConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

@PropertySources(
@PropertySource("classpath:jdbcConfig.properties")
)
public class JdbcConfig {

@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;

/**
* 用于创建一个 QueryRunner 对象
* @param dataSource
* @return
*/
@Bean(name = "runner")
@Scope("prototype")
public QueryRunner createQueryRunner(DataSource dataSource) {
return new QueryRunner(dataSource);
}

@Bean(name = "dataSource")
public DataSource createDataSource() throws PropertyVetoException {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
return ds;
}

}

测试

​ 由于不再使用 XML 文件,我们调用 bean 工厂的方法就要有变化,我们通过一下语句来指定配置类

1
2
3
4
5
6
private ApplicationContext context;

@Before
public void init() {
context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
}

​ 这样我们就指定了SpringConfiguration.java为配置类,并且还可以直接使用它内部使用的子配置类

-------------本文结束感谢您的阅读-------------