上篇文章主要讲了springIoc的配置文件注入和注解式注入
本文主要内容:
配置类以及Spring整合Junit
我们知道,要在java类使用注解或者是依赖注入,我们通常需要在配置文件写这些内容:
<!-- 告知spring在创建容器时要扫描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--配置QueryRunner-->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<!--注入数据源-->
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--连接数据库的必备信息-->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="user" value="root"></property>
<property name="password" value="1234"></property>
</bean>
如果是注解注入,需要在类名头上写一些注解表示这个类作为Bean注入到IOC容器中,那么
可不可以在java类上写一个注解的形式来表示这个类作为一个配置类呢?
答案是可行的,我们需要这么写:
@Configuration
@ComponentScan("com.itheima") //相当于扫描扫描包
public class SpringConfiguration {
private String driver="com.mysql.jdbc.Driver";
private String url="jdbc:mysql://localhost:3306/eesy";
private String username="root";
private String password="1234";
@Bean
public QueryRunner createQueryRunner( DataSource dataSource){
return new QueryRunner(dataSource);
}
@Bean
public DataSource createDataSource(){
try {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
return ds;
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
使用到的注解:
@Bean
范围:@Target({ElementType.METHOD})
作用:把当前方法的返回值作为一个Bean注入到IOC容器当中
细节:当这个Bean被调用时,查找规则和@Autowire一样
@Configuration
范围:@Target({ElementType.TYPE})
作用:指定当前类是一个配置类
细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。
@ComponentScan
范围:@Target({ElementType.TYPE})
作用:用于通过注解指定spring在创建容器时要扫描的包
属性:value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。
我们使用此注解就等同于在xml中配置了:
<context:component-scan base-package="com.itheima"></context:component-scan>
但是配置文件的内容就可以移除了,但是配置文件可以删掉吗?显然不能获取IOC核心容器的对象是根据配配置文件的路径获得的,删掉会报错。还记得上篇文章讲到
ApplicationContext的三个常用实现类:
ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下
FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
AnnotationConfigApplicationContext:它是用于读取注解创建容器的,今天我们将使用这个实现类
//参数填写注解类的字节码文件对象
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
IOC对注解类管理细节
我们先看看这种写法
@Configuration
@ComponentScan("com.itheima")
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {
}
和上面的写法比多了两个注解
@Import
范围:@Target({ElementType.TYPE})
作用:用于导入其他的配置类
属性:
value:用于指定其他配置类的字节码。
当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类
@PropertySource
范围:@Target({ElementType.TYPE})
作用:用于指定properties文件的位置
属性:
value:指定文件的名称和路径。
关键字:classpath,表示类路径下
意思就是把JdbcConfig这个类作为子配置类导入,我们来看一看这个类:
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;
@Bean(name="runner")
@Scope("prototype")
public QueryRunner createQueryRunner( DataSource dataSource){
return new QueryRunner(dataSource);
}
@Bean()
public DataSource createDataSource(){
try {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
return ds;
}catch (Exception e){
throw new RuntimeException(e);
}
}
@Value注解就相当于去jdbcConfig.properties这个配置文件找到对应的值赋给使用改注解的成员变量了
//这是 jdbcConfig.properties这个配置文件的内容:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234
Spring整合Junit
现在我们都知道,调用Bean的方法首先需要初始化IOC核心容器,然后输入id获得我们想要的Bean,这样才能调用Bean的方法,但是对于测试人员来说,他们可能不懂Spring框架技术,接下来我们将在Spring整合Junit
步骤如下:
1、导入spring整合junit的jar(坐标)
2、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
@Runwith
3、告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置
@ContextConfiguration
locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
classes:指定注解类所在地位置
我们写一个demo:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class ClassName{
@Autowired
private Interface n ;
@Test
public void MethodName() {
//3.执行方法
List<String> accounts = nIPML.method();
for(String a: accounts){
System.out.println(a);
}
}