Spring_two

Spring_two

基于注解的IOC配置

准备工作(参考上一篇)

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. </dependencies>

创建接口AccountDao.java

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao {
  5. /**
  6. * 模拟保存账户
  7. */
  8. void saveAccount();
  9. }

创建实现类AccountDaoImpl.java

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl implements AccountDao {
  5. public void saveAccount(){
  6. System.out.println("AccountDaoImpl实现了接口AccountDao的保存方法");
  7. }
  8. }

创建接口AccountService.java

  1. /**
  2. * 账户业务层的接口
  3. */
  4. public interface AccountService {
  5. /**
  6. * 模拟保存账户
  7. */
  8. void saveAccount();
  9. }

创建接口的实现类,AccountServiceImpl.java

  1. public class AccountServiceImpl implements AccountService {
  2. //注入
  3. private AccountDao accountDao;
  4. public void setAccountDao(AccountDao accountDao) {
  5. this.accountDao = accountDao;
  6. }
  7. public void saveAccount(){
  8. accountDao.saveAccount();
  9. }
  10. }

用applicationContext.xml的方式完成配置(配置文件的IOC和DI)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl"></bean>
  7. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  8. <property name="accountDao" ref="accountDao"></property>
  9. </bean>
  10. </beans>

测试类

  1. public class Client {
  2. public static void main(String[] args) {
  3. // 工厂类加载spring的配置文件
  4. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  5. AccountService accountService = ac.getBean("accountService", AccountService.class);
  6. accountService.saveAccount();
  7. }
  8. }

注解配置-控制反转IOC

以前的XML配置

  1. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl" scope="" init-method="" destroy-method="">
  2. <property name="" value="" | ref=""></property>
  3. </bean>

用于创建对象的

​ 他们的作用就和在XML配置文件中编写一个标签实现的功能是一样的 
(1)@Component: 

  • ​ 作用:用于把当前类对象存入spring容器中 
  • ​ 属性: 
    value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。

(2)Spring中提供了@Component的衍生注解:

  • @Controller :用来修饰WEB层类(控制层)(springMVC延用了该注解)
  • @Service :用来修饰service层类(业务层)
  • @Repository :用来修饰DAO层类(持久层)

以上三个注解他们的作用和属性与Component是一模一样。 
他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. @Repository("accountDao1")//指定以”accountDao1”的ID存入Spring
  5. public class AccountDaoImpl implements AccountDao {
  6. public void saveAccount(){
  7. System.out.println("AccountDaoImpl实现了接口AccountDao的保存方法");
  8. }
  9. }

替代了

1561866842891

AccountServiceImpl.java

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. @Service("accountService1")//指定以”accountService”的ID存入Spring
  5. public class AccountServiceImpl implements AccountService {
  6. private AccountDao accountDao = new AccountDaoImpl();
  7. public void saveAccount(){
  8. accountDao.saveAccount();
  9. }
  10. }

替代了

1561866927791

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!--注意约束新增了context-->
  10. <!--告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为
  11. context名称空间和约束中-->
  12. <context:component-scan base-package="com.it"></context:component-scan>
  13. </beans>

注解配置-依赖注入 DI

用于注入数据的

​ 它们的作用就和在xml配置文件中的bean标签中写一个标签的作用是一样的

​ @Autowired
​ 基于spring 
作用:

  • 自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功

  • 如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。

  • 如果Ioc容器中有多个类型匹配时: 
    先按照类型匹配,如果不能匹配上,会按照属性的名称进行匹配

出现位置: 
可以是变量上,也可以是set方法上

细节: 
在使用注解注入时,set方法就不是必须的了。

​ @Qualifier
​ 配合@Autowired注解一起使用

​ 作用:在按照类型注入的基础之上再按照名称注入。

​ 属性: 
​ value:用于指定注入bean的id。 

​ @Resource 
​ JSR-250标准(基于jdk)

​ 作用:直接按照bean的id名称注入。如果id属性不存在,可以再按照类型注入。它可以独立使用 

​ 属性: 
​ name:用于指定bean的id,如果指定name,只能按照bean的id注入,不能按照类型注入。 

注意: 
以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现(使用@Value)。

@Value 
作用:用于注入基本类型和String类型的数据 
属性: 
value:用于指定数据的值。使用${表达式}可以读取配置文件(.properties文件)的信息

  1. @Value(value = "张三")
  2. private String name;
  3. @Value(value = "18")
  4. private Integer age;
  5. public void saveAccount() {
  6. System.out.println("执行AccountServiceImpl的保存账号方法 name:"+name+" age:"+age);
  7. accountDao.saveAccount();
  8. }

1561867354896

  1. @Service("accountService")
  2. public class AccountServiceImpl implements AccountService {
  3. @Autowired
  4. @Qualifier("accountDao1")
  5. //@Resource(name = "accountDao2")
  6. private AccountDao accountDao;
  7. public void saveAccount(){
  8. accountDao.saveAccount();
  9. }
  10. }

替代了

1561867527473


注解配置-作用域

用于改变作用范围的

他们的作用就和在bean标签中使用scope属性实现的功能是一样的

​ @Scope 

  • 作用:用于指定bean的作用范围

  • 属性: 
    value:指定范围的取值。

常用取值:singleton prototype

  1. @Service("accountService")
  2. @Scope("prototype")
  3. public class AccountServiceImpl implements AccountService {
  4. @Autowired
  5. @Qualifier("accountDao1")
  6. //@Resource(name = "accountDao2")
  7. private AccountDao accountDao = null;
  8. public AccountServiceImpl(){
  9. System.out.println("构造方法...测试多例");
  10. }
  11. public void saveAccount(){
  12. accountDao.saveAccount();
  13. }
  14. }

1561868018781


注解配置-初始化和销毁(单例)

配置AccountServiceImpl.java

  1. @Service("accountService")
  2. //@Scope("prototype")// 测试初始化和销毁,不能使用多例
  3. public class AccountServiceImpl implements AccountService {
  4. @Autowired
  5. @Qualifier("accountDao1")
  6. //@Resource(name = "accountDao2")
  7. private AccountDao accountDao = null;
  8. public AccountServiceImpl(){
  9. System.out.println("构造方法...");
  10. }
  11. @PostConstruct
  12. public void init(){
  13. System.out.println("初始化方法执行了");
  14. }
  15. @PreDestroy
  16. public void destroy(){
  17. System.out.println("销毁方法执行了");
  18. }
  19. public void saveAccount(){
  20. accountDao.saveAccount();
  21. }
  22. }

等同于配置文件:

  1. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl" init-method=”init” destory-method=”destory”> </bean>

使用springIoC的实现账户的CRUD

导入坐标,pom.xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>commons-dbutils</groupId>
  9. <artifactId>commons-dbutils</artifactId>
  10. <version>1.4</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>mysql</groupId>
  14. <artifactId>mysql-connector-java</artifactId>
  15. <version>5.1.6</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>c3p0</groupId>
  19. <artifactId>c3p0</artifactId>
  20. <version>0.9.1.2</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>junit</groupId>
  24. <artifactId>junit</artifactId>
  25. <version>4.12</version>
  26. </dependency>
  27. </dependencies>

创建数据库

  1. create table account(
  2. id int primary key auto_increment,
  3. name varchar(40),
  4. money float
  5. )character set utf8 collate utf8_general_ci;
  6. insert into account(name,money) values('aaa',1000);
  7. insert into account(name,money) values('bbb',1000);
  8. insert into account(name,money) values('ccc',1000);

创建实体

  1. /**
  2. * 账户的实体类
  3. */
  4. public class Account implements Serializable {
  5. private Integer id;
  6. private String name;
  7. private Float money;
  8. // set和get方法...
  9. }

创建接口AccountDao.java 
实现CRUD操作

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao {
  5. /**
  6. * 查询所有
  7. * @return
  8. */
  9. List<Account> findAllAccount();
  10. /**
  11. * 查询一个
  12. * @return
  13. */
  14. Account findAccountById(Integer accountId);
  15. /**
  16. * 保存
  17. * @param account
  18. */
  19. void saveAccount(Account account);
  20. /**
  21. * 更新
  22. * @param account
  23. */
  24. void updateAccount(Account account);
  25. /**
  26. * 删除
  27. * @param acccountId
  28. */
  29. void deleteAccount(Integer acccountId);
  30. }

创建接口的实现类AccountDaoImpl.java

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl implements AccountDao {
  5. private QueryRunner runner;
  6. public void setRunner(QueryRunner runner) {
  7. this.runner = runner;
  8. }
  9. public List<Account> findAllAccount() {
  10. try{
  11. return runner.query("select * from account",new BeanListHandler<Account>(Account.class));
  12. }catch (Exception e) {
  13. throw new RuntimeException(e);
  14. }
  15. }
  16. public Account findAccountById(Integer accountId) {
  17. try{
  18. return runner.query("select * from account where id = ? ",new BeanHandler<Account>(Account.class),accountId);
  19. }catch (Exception e) {
  20. throw new RuntimeException(e);
  21. }
  22. }
  23. public void saveAccount(Account account) {
  24. try {
  25. runner.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney());
  26. } catch (SQLException e) {
  27. throw new RuntimeException(e);
  28. }
  29. }
  30. public void updateAccount(Account account) {
  31. try{
  32. runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  33. }catch (Exception e) {
  34. throw new RuntimeException(e);
  35. }
  36. }
  37. public void deleteAccount(Integer accountId) {
  38. try{
  39. runner.update("delete from account where id=?",accountId);
  40. }catch (Exception e) {
  41. throw new RuntimeException(e);
  42. }
  43. }
  44. }

创建接口AccountService.java

  1. /**
  2. * 账户的业务层接口
  3. */
  4. public interface AccountService {
  5. /**
  6. * 查询所有
  7. * @return
  8. */
  9. List<Account> findAllAccount();
  10. /**
  11. * 查询一个
  12. * @return
  13. */
  14. Account findAccountById(Integer accountId);
  15. /**
  16. * 保存
  17. * @param account
  18. */
  19. void saveAccount(Account account);
  20. /**
  21. * 更新
  22. * @param account
  23. */
  24. void updateAccount(Account account);
  25. /**
  26. * 删除
  27. * @param acccountId
  28. */
  29. void deleteAccount(Integer acccountId);
  30. }

创建接口的实现类AccountServiceImpl.java

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. public class AccountServiceImpl implements AccountService {
  5. private AccountDao accountDao;
  6. public void setAccountDao(AccountDao accountDao) {
  7. this.accountDao = accountDao;
  8. }
  9. public List<Account> findAllAccount() {
  10. return accountDao.findAllAccount();
  11. }
  12. public Account findAccountById(Integer accountId) {
  13. return accountDao.findAccountById(accountId);
  14. }
  15. public void saveAccount(Account account) {
  16. accountDao.saveAccount(account);
  17. }
  18. public void updateAccount(Account account) {
  19. accountDao.updateAccount(account);
  20. }
  21. public void deleteAccount(Integer acccountId) {
  22. accountDao.deleteAccount(acccountId);
  23. }
  24. }

编写测试类com.it.test,AccountServiceTest.java

  1. /**
  2. * 使用Junit单元测试:测试我们的配置
  3. */
  4. public class AccountServiceTest {
  5. @Test
  6. public void testFindAll() {
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. AccountService as = (AccountService) ac.getBean("accountService");
  9. //3.执行方法
  10. List<Account> accounts = as.findAllAccount();
  11. for(Account account : accounts){
  12. System.out.println(account);
  13. }
  14. }
  15. @Test
  16. public void testFindOne() {
  17. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  18. AccountService as = (AccountService) ac.getBean("accountService");
  19. //3.执行方法
  20. Account account = as.findAccountById(1);
  21. System.out.println(account);
  22. }
  23. @Test
  24. public void testSave() {
  25. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  26. AccountService as = (AccountService) ac.getBean("accountService");
  27. Account account = new Account();
  28. account.setName("test");
  29. account.setMoney(12345f);
  30. //3.执行方法
  31. as.saveAccount(account);
  32. }
  33. @Test
  34. public void testUpdate() {
  35. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  36. AccountService as = (AccountService) ac.getBean("accountService");
  37. //3.执行方法
  38. Account account = as.findAccountById(4);
  39. account.setMoney(23456f);
  40. as.updateAccount(account);
  41. }
  42. @Test
  43. public void testDelete() {
  44. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  45. AccountService as = (AccountService) ac.getBean("accountService");
  46. //3.执行方法
  47. as.deleteAccount(4);
  48. }
  49. }

编写applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!-- 配置Service -->
  7. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  8. <!-- 注入dao -->
  9. <property name="accountDao" ref="accountDao"></property>
  10. </bean>
  11. <!--配置Dao对象-->
  12. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  13. <!-- 注入QueryRunner -->
  14. <property name="runner" ref="runner"></property>
  15. </bean>
  16. <!--配置QueryRunner,设置prototype为多例,表示每次调用都获取一个新的连接对象-->
  17. <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  18. <!--注入数据源(构造方法)-->
  19. <constructor-arg name="ds" ref="dataSource"></constructor-arg>
  20. </bean>
  21. <!-- 配置数据源 -->
  22. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  23. <!--连接数据库的必备信息-->
  24. <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  25. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  26. <property name="user" value="root"></property>
  27. <property name="password" value="root"></property>
  28. </bean>
  29. </beans>

添加jdbc.properties文件

这里,也可以使用spring的${}动态赋值表达式,读取属性文件

第一步:添加jdbc.properties文件

  1. jdbc.driver=com.mysql.jdbc.Driver
  2. jdbc.url=jdbc:mysql://localhost:3306/itcastspring
  3. jdbc.username=root
  4. jdbc.password=root

第二步:修改applicationContext.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:context="http://www.springframework.org/schema/context"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/context
  7. http://www.springframework.org/schema/context/spring-context.xsd">
  8. <context:property-placeholder location="jdbc.properties"></context:property-placeholder>
  9. <!-- 配置数据源 -->
  10. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  11. <!--连接数据库的必备信息-->
  12. <property name="driverClass" value="${jdbc.driver}"></property>
  13. <property name="jdbcUrl" value="${jdbc.url}"></property>
  14. <property name="user" value="${jdbc.username}"></property>
  15. <property name="password" value="${jdbc.password}"></property>
  16. </bean>
  17. </beans>

使用import加载多个applicationContext.xml

让程序加载多个spring的配置文件,对spring的配置文件细分 
applicationContext.xml:加载第三方的配置(数据源、QueryRunner) 
applicationContext-dao.xml:加载自己创建的Dao对象 
applicationContext-service.xml:加载自己创建的Service对象 
applicationContext-redis.xml、applicationContext-mq.xml、applicationContext-mybatis.xml等

1561869226921

需要使用import加载 
在applicationContext.xml中添加:

  1. <!--加载其他spring的配置文件-->
  2. <import resource="classpath:applicationContext-service.xml"></import>
  3. <import resource="classpath:applicationContext-dao.xml"></import>

使用注解配置IOC

使用DBUtils对账号表实现CRUD

创建数据库

  1. create table account(
  2. id int primary key auto_increment,
  3. name varchar(40),
  4. money float
  5. )character set utf8 collate utf8_general_ci;
  6. insert into account(name,money) values('aaa',1000);
  7. insert into account(name,money) values('bbb',1000);
  8. insert into account(name,money) values('ccc',1000);

接口的实现类AccountDaoImpl.java修改

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. @Repository("accountDao")
  5. public class AccountDaoImpl implements AccountDao {
  6. @Autowired
  7. private QueryRunner runner;
  8. public List<Account> findAllAccount() {
  9. try{
  10. return runner.query("select * from account",new BeanListHandler<Account>(Account.class));
  11. }catch (Exception e) {
  12. throw new RuntimeException(e);
  13. }
  14. }
  15. public Account findAccountById(Integer accountId) {
  16. try{
  17. return runner.query("select * from account where id = ? ",new BeanHandler<Account>(Account.class),accountId);
  18. }catch (Exception e) {
  19. throw new RuntimeException(e);
  20. }
  21. }
  22. public void saveAccount(Account account) {
  23. try{
  24. runner.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney());
  25. }catch (Exception e) {
  26. throw new RuntimeException(e);
  27. }
  28. }
  29. public void updateAccount(Account account) {
  30. try{
  31. runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  32. }catch (Exception e) {
  33. throw new RuntimeException(e);
  34. }
  35. }
  36. public void deleteAccount(Integer accountId) {
  37. try{
  38. runner.update("delete from account where id=?",accountId);
  39. }catch (Exception e) {
  40. throw new RuntimeException(e);
  41. }
  42. }
  43. }

接口的实现类AccountServiceImpl.java修改

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. @Service("accountService")
  5. public class AccountServiceImpl implements AccountService {
  6. @Autowired
  7. private AccountDao accountDao;
  8. public List<Account> findAllAccount() {
  9. return accountDao.findAllAccount();
  10. }
  11. public Account findAccountById(Integer accountId) {
  12. return accountDao.findAccountById(accountId);
  13. }
  14. public void saveAccount(Account account) {
  15. accountDao.saveAccount(account);
  16. }
  17. public void updateAccount(Account account) {
  18. accountDao.updateAccount(account);
  19. }
  20. public void deleteAccount(Integer acccountId) {
  21. accountDao.deleteAccount(acccountId);
  22. }
  23. }

applicationContext.xml修改

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!-- 告知spring在创建容器时要扫描的包 -->
  10. <context:component-scan base-package="com.it"></context:component-scan>
  11. <!--配置QueryRunner-->
  12. <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  13. <!--注入数据源-->
  14. <constructor-arg name="ds" ref="dataSource"></constructor-arg>
  15. </bean>
  16. <!-- 配置数据源 -->
  17. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  18. <!--连接数据库的必备信息-->
  19. <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  20. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  21. <property name="user" value="root"></property>
  22. <property name="password" value="root"></property>
  23. </bean>
  24. </beans>

企业开发的时候:一般配置文件(xml)+注解混合使用

配置文件:

  • 第三方提供的对象(QueryRunner、C3P0),可以由配置文件XML完成
  • 自己创建的对象(Controller、Service、Dao、工具类Utils),可以由注解进行完成

使用spring的注解配置,去掉applicationContext.xml中所有配置

准备:

  • 导入Account.java
  • 导入AccountDao.java和AccountDaoImpl.java
  • 导入AccountService.java和AccountServiceImpl.java
  • 导入AccountServiceTest.java的测试类

@Configuration注解

创建包config,创建SpringConfiguration.java类

  1. @Configuration
  2. public class SpringConfiguration {
  3. }

表示该类是一个配置类,它的作用和applicationContext.xml是一样的

spring5中的新注解 
@Configuration 
作用:指定当前类是一个配置类,如同取代applicationContext.xml中的配置 
细节:当配置类作为AnnotationConfigApplicationContext对象创建时,该注解可以不写。


@ComponentScan注解

@ComponentScan

作用:用于通过注解指定spring在创建容器时要扫描的包

属性: 
value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包的范围。

我们使用此注解就等同于在xml中配置了:

  1. <context:component-scan base-package="com.it"></context:component-scan
  1. @Configuration
  2. @ComponentScan(value = {"com.it"})
  3. public class SpringConfiguration {
  4. }

@Bean注解

@Bean

作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中

属性: 
name:用于指定bean的id。当不写时,默认值是当前方法的名称

依赖注入细节:

我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象,如果有bean对象,将对象通过方法的形参注入到方法中使用。查找的方式和Autowired注解的作用是一样的

  1. @Configuration//
  2. @ComponentScan(value = {"com.it"})
  3. public class SpringConfiguration {
  4. /**
  5. * 用于创建一个QueryRunner对象
  6. * @param dataSource
  7. * @return
  8. */
  9. @Bean(name="runner")
  10. @Scope("prototype")
  11. public QueryRunner createQueryRunner(DataSource dataSource){
  12. return new QueryRunner(dataSource);
  13. }
  14. /**
  15. * 创建数据源对象
  16. * @return
  17. */
  18. @Bean(name="ds")
  19. public DataSource createDataSource(){
  20. try {
  21. ComboPooledDataSource ds = new ComboPooledDataSource();
  22. ds.setDriverClass("com.mysql.jdbc.Driver");
  23. ds.setJdbcUrl("jdbc:mysql://localhost:3306/itcastspring");
  24. ds.setUser("root");
  25. ds.setPassword("root");
  26. return ds;
  27. }catch (Exception e){
  28. throw new RuntimeException(e);
  29. }
  30. }
  31. }

1561869741733


工厂AnnotationConfigApplicationContext.java

当配置类作为AnnotationConfigApplicationContext对象创建的参数时,@Configuration注解可以不写。

使用AccountServiceTest.java测试查询:

  1. public class AccountServiceTest {
  2. @Test
  3. public void testFindAll() {
  4. ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
  5. AccountService as = (AccountService)ac.getBean("accountService");
  6. //3.执行方法
  7. List<Account> accounts = as.findAllAccount();
  8. for(Account account : accounts){
  9. System.out.println(account);
  10. }
  11. }
  12. }

创建测试类QueryRunnerTest.java,测试QueryRunner是否是单例。

  1. /**
  2. * 测试queryrunner是否单例
  3. */
  4. public class QueryRunnerTest {
  5. @Test
  6. public void testQueryRunner(){
  7. //1.获取容易
  8. ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
  9. //2.获取queryRunner对象
  10. QueryRunner runner = ac.getBean("runner",QueryRunner.class);
  11. QueryRunner runner1 = ac.getBean("runner",QueryRunner.class);
  12. System.out.println(runner == runner1);
  13. }
  14. }

@Import注解

@Import 
作用:用于导入其他的配置类 
属性:

value:用于指定其他配置类的字节码。

当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类

相当于applicationContext.xml中的

第一步:创建配置类,JdbcConfig.java

将配置都放置到JdbcConfig中

  1. public class JdbcConfig {
  2. /**
  3. * 用于创建一个QueryRunner对象
  4. * @param dataSource
  5. * @return
  6. */
  7. @Bean(name="runner")
  8. @Scope("prototype")
  9. public QueryRunner createQueryRunner(DataSource dataSource){
  10. return new QueryRunner(dataSource);
  11. }
  12. /**
  13. * 创建数据源对象
  14. * @return
  15. */
  16. @Bean(name="ds")
  17. public DataSource createDataSource(){
  18. try {
  19. ComboPooledDataSource ds = new ComboPooledDataSource();
  20. ds.setDriverClass("com.mysql.jdbc.Driver");
  21. ds.setJdbcUrl("jdbc:mysql://localhost:3306/itcastspring");
  22. ds.setUser("root");
  23. ds.setPassword("root");
  24. return ds;
  25. }catch (Exception e){
  26. throw new RuntimeException(e);
  27. }
  28. }
  29. }

用SpringConfiguration.java引入JdbcConfig的配置

  1. //@Configuration
  2. @ComponentScan(value = {"com.it"})
  3. @Import(value= JdbcConfig.class)
  4. public class SpringConfiguration {
  5. }

@PropertySource注解

@PropertySource

作用:用于指定properties文件的位置

属性: 
value:指定文件的名称和路径。

关键字:classpath,表示类路径下

在resource下创建 jdbcConfig.properties文件

  1. jdbc.driver=com.mysql.jdbc.Driver
  2. jdbc.url=jdbc:mysql://localhost:3306/itcastspring
  3. jdbc.username=root
  4. jdbc.password=root

配置SpringConfiguration.java

  1. //@Configuration
  2. @ComponentScan(value = {"com.it"})
  3. @Import(value= JdbcConfig.class)
  4. @PropertySource("classpath:jdbcConfig.properties")
  5. public class SpringConfiguration {
  6. }

配置JdbcConfig.java

  1. **
  2. * spring连接数据库相关的配置类
  3. */
  4. public class JdbcConfig {
  5. @Value("${jdbc.driver}")
  6. private String driver;
  7. @Value("${jdbc.url}")
  8. private String url;
  9. @Value("${jdbc.username}")
  10. private String username;
  11. @Value("${jdbc.password}")
  12. private String password;
  13. /**
  14. * 用于创建一个QueryRunner对象
  15. * @param dataSource
  16. * @return
  17. */
  18. @Bean(name="runner")
  19. @Scope("prototype")
  20. public QueryRunner createQueryRunner(DataSource dataSource){
  21. return new QueryRunner(dataSource);
  22. }
  23. /**
  24. * 创建数据源对象
  25. * @return
  26. */
  27. @Bean(name="ds")
  28. public DataSource createDataSource(){
  29. try {
  30. ComboPooledDataSource ds = new ComboPooledDataSource();
  31. // ds.setDriverClass("com.mysql.jdbc.Driver");
  32. // ds.setJdbcUrl("jdbc:mysql://localhost:3306/itcastspring");
  33. // ds.setUser("root");
  34. // ds.setPassword("root");
  35. ds.setDriverClass(driver);
  36. ds.setJdbcUrl(url);
  37. ds.setUser(username);
  38. ds.setPassword(password);
  39. return ds;
  40. }catch (Exception e){
  41. throw new RuntimeException(e);
  42. }
  43. }
  44. }

@Qualifier注解

作用:如果spring容器中出现了多个数据源类型,使用该注解指定注入的数据源。

修改JdbcConfig.java的配置。

  1. /**
  2. * 用于创建一个QueryRunner对象
  3. * @param dataSource
  4. * @return
  5. */
  6. @Bean(name="runner")
  7. @Scope("prototype")
  8. public QueryRunner createQueryRunner(@Qualifier(value = "ds2") DataSource dataSource){
  9. return new QueryRunner(dataSource);
  10. }
  11. /**
  12. * 创建数据源对象
  13. * @return
  14. */
  15. @Bean(name="ds1")
  16. public DataSource createDataSource(){
  17. try {
  18. ComboPooledDataSource ds = new ComboPooledDataSource();
  19. ds.setDriverClass(driver);
  20. ds.setJdbcUrl("jdbc:mysql:///itcastspring");
  21. ds.setUser(username);
  22. ds.setPassword(password);
  23. return ds;
  24. }catch (Exception e){
  25. throw new RuntimeException(e);
  26. }
  27. }
  28. @Bean(name="ds2")
  29. public DataSource createDataSource2(){
  30. try {
  31. ComboPooledDataSource ds = new ComboPooledDataSource();
  32. ds.setDriverClass(driver);
  33. ds.setJdbcUrl("jdbc:mysql:///test");
  34. ds.setUser(username);
  35. ds.setPassword(password);
  36. return ds;
  37. }catch (Exception e){
  38. throw new RuntimeException(e);
  39. }
  40. }

为什么全注解开发呢?

因为springboot框架中的底层会体现,全注解的配置


使用spring整合Junit

什么是main方法?

main方法,应用程序的入口

2、什么是junit方法?

junit单元测试中,没有main方法也能执行

​ 因为junit集成了一个main方法

​ 该方法就会判断当前测试类中哪些方法有 @Test注解

​ junit就让有@Test注解的方法执行

3、junit方法测试spring的IOC和DI的问题?

junit不会管我们是否采用spring框架

​ 在执行测试方法时,junit根本不知道我们是不是使用了spring框架

​ 所以也就不会为我们读取配置文件(基于XML)、配置类(基于注解)、并创建spring核心容器

4、总结:

由以上三点可知

​ 当测试方法执行时,没有Ioc容器,就算写了Autowired注解,也无法实现注入

​ 但是如何通过junit加载Ioc容器(即srping容器)呢?


Spring整合junit

Spring整合junit的配置

导入spring整合junit的jar(坐标)

  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-test</artifactId>
  4. <version>5.0.2.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>junit</groupId>
  8. <artifactId>junit</artifactId>
  9. <version>4.12</version>
  10. </dependency>
  • 使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的

  • 使用:@Runwith,加载SpringJUnit4ClassRunner.class

  • 告知spring的运行器,spring和ioc创建是基于xml还是基于注解的,并且说明位置

  • 使用@ContextConfiguration

locations:指定xml文件的位置,加上classpath关键字,表示在类路径下

@ContextConfiguration(locations = **"classpath:applicationContext.xml"**)

classes:指定注解类所在地位置

@ContextConfiguration(classes = SpringConfiguration.**class**)

注意:当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上

  1. /**
  2. * 使用Junit单元测试:测试我们的配置
  3. * Spring整合junit的配置
  4. * 1、导入spring整合junit的jar(坐标)
  5. * 2、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
  6. * @Runwith
  7. * 3、告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置
  8. * @ContextConfiguration
  9. * locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
  10. * classes:指定注解类所在地位置
  11. *
  12. * 当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上
  13. */
  14. @RunWith(SpringJUnit4ClassRunner.class)
  15. @ContextConfiguration(classes = SpringConfiguration.class)
  16. public class AccountServiceTest {
  17. @Autowired
  18. private AccountService as;
  19. @Test
  20. public void testFindAll() {
  21. //3.执行方法
  22. List<Account> accounts = as.findAllAccount();
  23. for(Account account : accounts){
  24. System.out.println(account);
  25. }
  26. }
  27. }
posted @ 2019-06-30 13:00  不穿格子衫的徍爺  阅读(143)  评论(0编辑  收藏  举报