【Spring】08 后续的学习补充 vol2
1、【纯注解配置实现】
首先实现纯注解配置的第一件事情就是删除XML文件
然后编写一个类用于代替XML文件实现配置功能:
使用@Configuration将这个类注册为Spring容器
使用@ComponentScan表示我们自己的包目录扫描
扫描的类会被这个配置注册成Bean,一般那些类会被标记有叶子
使用@PropertySource指定配置文件路径
文件内的信息可以被表达式获取到
使用@Bean注册
用于jar包的资源获取,XML我们使用的是bean标签
当然还需要以一个方法的形式返回:
方法的名字就是Bean的ID属性,方法的返回类型即Class属性
如果我们不想使用方法的名字,可以对Bean再赋值名字的值:
使用@Scope注解改变Bean的范围
当然,如果我们希望这个Bean不是单例的,在XML中则设置scope属性
使用@Import合并配置类
Spring允许我们设置多个配置类,这和设置多个XML配置文件是一样的
在XML文件中我们使用import标签将其他XML文件统一导入到一个文件中,这也是一个道理
例如这里配置了一个Jdbc配置类:
我们就可以把他导入到我们上面的配置类去:
然后我们加载容器实例的时候就不需要分开导入了
注意我们是使用这个注解加载的容器实例:
@Autowired再谈自动装配:
首先自动装配是针对引用数据类型的,例如我们的dao,service,包括一些其他的数据源等对象
基本数据类型,或者说简单的常用数据类型无法使用@Autowired(这种玩意你让Spring装配干嘛,直接赋值不就行了)
还有个要求是被装配的对象所属的类必须也被Spring容器注册了
缺陷:自动装配要求容器中只能有一个符合要求的类型,才可以装配上
如果你注册了多个同类型的bean,该注解无法装配,因为spring不知道你到底需要装配哪一个bean
@Autowired在全注解中的应用:
在bean方法的参数中如果需要注入引用类型,是默认使用自动装配完成的
例如这个例子:
数据源是默认打上了自动装配注解的
使用@Qulifier指定要注入的同类型bean
回到上面的多个同类型的问题,如果我们配置了多个数据源,那么可以在这里添加此注解即可
其意义是指定bean的id属性为注解所指定的相匹配的同类型bean来注入
使用@Value赋值
一般用于对一些类的普通属性进行赋值
这里我为了创建数据源图省事就直接对参数打上注解进行赋值
2、【SpringTest 使用】
为什么需要Spring-Test?
因为Spring容器固定的需要这样手写的方式加载出来:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringApplicationConfiguration.class); QueryRunner queryRunner = applicationContext.getBean("queryRunner", QueryRunner.class);
所以测试的姿势应该更简单些
需要对应的依赖:
特别注意Junit版本不得低于4.12,不然Spring都加载不到
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.7.RELEASE</version> </dependency>
然后是测试类的编写:
@Runwith注解测试类使用何种资源运行
@ContextConfiguration用于加载容器配置,一个XML,一个配置类这两种
一个是不要忘记加载容器,第二个是不要加载错误的配置资源
自己写什么配置方式,就加载什么配置资源
代码:
import cn.echo42.config.SpringApplicationConfiguration; import cn.echo42.pojo.User; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author DaiZhiZhou * @file Spring * @create 2020-07-27 16:08 */ @RunWith(SpringJUnit4ClassRunner.class) // 指定运行类 // @ContextConfiguration(locations = "classpath:xxx-context.xml") xml文件加载 @ContextConfiguration(classes = SpringApplicationConfiguration.class) // 配置类加载 指定加载容器 public class SpringTest { @Autowired private QueryRunner queryRunner; @Test public void jdbcTest() throws Exception{ for (User user : queryRunner.query("SELECT * FROM `sys_user`", new BeanListHandler<User>(User.class))) { System.out.println(user); } } }
import cn.echo42.config.SpringApplicationConfiguration; import cn.echo42.pojo.User; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.List; /** * @author DaiZhiZhou * @file Spring * @create 2020-07-27 13:43 */ public class AnnotationTest { @Test public void annotationGet() throws Exception { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringApplicationConfiguration.class); QueryRunner queryRunner = applicationContext.getBean("queryRunner", QueryRunner.class); System.out.println(queryRunner); List<User> userList = queryRunner.query("SELECT * FROM `sys_user`", new BeanListHandler<User>(User.class)); for (User user : userList) { System.out.println(user); } } }
package cn.echo42.config; import com.alibaba.druid.pool.DruidDataSource; import org.apache.commons.dbutils.QueryRunner; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.*; import javax.sql.DataSource; /** * @author DaiZhiZhou * @file Spring * @create 2020-07-27 14:37 */ @Configuration // 表示注解该类为一个配置类 @ComponentScan("cn.echo42") // 指定spring在创建容器时要扫描的包,一般直接扫描总目录 @PropertySource("classpath:jdbc.properties") //指定properties文件的位置 public class SpringApplicationConfiguration { // 在这里引用外部Jar包的资源 @Bean("queryRunner") @Scope("prototype") public QueryRunner getQueryRunner(@Qualifier("dataSource") DataSource dataSource){ return new QueryRunner(dataSource); } @Bean("dataSource") // public DataSource getDataSource( @Value("${jdbc.driverClassName}") String driver, @Value("${jdbc.url}")String url, @Value("${jdbc.user}")String username, @Value("${jdbc.password}")String password ) { DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setDriverClassName(driver); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password); return druidDataSource; } }
jdbc.driverClassName = com.mysql.cj.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/oa?serverTimezone=GMT jdbc.user = root jdbc.password = 123456