zoukankan      html  css  js  c++  java
  • 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. }
  • 相关阅读:
    对MVC模式与MVVM模式的认识
    优雅降级和渐进增强
    入园第一天
    看看AQS阻塞队列和条件队列
    简单看看LockSupport和AQS
    简单看看LongAccumulator
    JUC中的原子操作类及其原理
    java并发基础知识
    简单看看es6解构赋值
    简单使用vue-cli
  • 原文地址:https://www.cnblogs.com/leccoo/p/11109429.html
Copyright © 2011-2022 走看看