Spring学习笔记(二)依赖注入

注:本文部分内容参考https://blog.csdn.net/ncepu_Chen/article/details/91903396#_454

依赖注入的三种数据类型

1.String与其他基本数据类型
2.其他bean类型
3.复杂类型/集合类型

依赖注入三种方式

1.构造函数注入

使用的标签:·<constructor-arg>用来定义构造函数的参数,其属性可大致分为两类:

       1. 指定给哪个参数赋值:
            index: 指定参数在构造函数参数列表的索引位置
            type: 指定参数在构造函数中的数据类型
            name: 指定参数在构造函数中的变量名,最常用的属性
       2. 指定赋给字段的值
               value: 给基本数据类型和String类型赋值
               ref: 给其它Bean类型的字段赋值,ref属性的值应为配置文件中配置的Bean的id

类结构如下:

public class AccountServiceImpl implements IAccountService {
   //如果是经常变化的数据,并不适用于注入的方式
   private String name;
   private Integer age;
   private Date birthday;
   public AccountServiceImpl(String name, Integer age, Date birthday) {
       this.name = name;
       this.age = age;
       this.birthday = birthday;
   }
}

xm文件配置如下:

    <bean id="accountService" class="cn.maoritian.service.impl.AccountServiceImpl">
       <constructor-arg name="name" value="myname"></constructor-arg>
       <constructor-arg name="age" value="18"></constructor-arg>

       <constructor-arg name="birthday" ref="now"></constructor-arg>
   </bean>
    <!--使用Date类的无参构造函数创建Date对象-->
   <bean id="now" class="java.util.Date" scope="prototype"></bean>

缺点: 如果在创建对象时用不到某个参数,我们也必须提供。所以此方法不常用!

2.Set方法注入(常用)

在类中提供需要注入成员属性的set方法,创建对象只调用要赋值属性的set方法.
涉及的标签:
属性:
name:要调用set方法名称
value: 给基本数据类型和String类型赋值
ref: 给其它Bean类型的字段赋值,ref属性的值应为配置文件中配置的Bean的id

public class AccountServiceImpl implements IAccountService {

 private String name;
 private Integer age;
 private Date birthday;

 public void setName(String name) {
 	this.name = name;
 }
 public void setAge(Integer age) {
 	this.age = age;
 }
 public void setBirthday(Date birthday) {
 	this.birthday = birthday;
 }

 @Override
 public void saveAccount() {
 	System.out.println(name+","+age+","+birthday);
 }
}
<!-- 使用Date类的无参构造函数创建Date对象 -->
<bean id="now" class="java.util.Date" scope="prototype"></bean>
<bean id="accountService" class="cn.maoritian.service.impl.AccountServiceImpl">
 <property name="name" value="myname"></property>
 <property name="age" value="21"></property>
 <!-- birthday字段为已经注册的bean对象,其id为now -->
 <property name="birthday" ref="now"></property>
</bean>

3.使用注解实现

将注解写在类的定义之中,首先将bean.xml文件的最开始部分换成如下代码,并使用context标签

<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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!--告知spring在创建容器时要扫描的包-->
    <context:component-scan base-package="com.itheima"></context:component-scan>
常用注解

一个bean标签如下:

 <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
         scope="" init-method="" destroy-method="">
      <property name="" value="" ref=""></property>
     </bean>
用于创建对象的注解

1.@Component
他的作用就和在xml配置文件中编写一样,将此类对象存入spring容器中,
属性: value:用于指定bean的id,若不指定,bean的id就是当前类名,并且首字母小写。
2.@Controller: 将当前表现层对象存入spring容器中
3.@Service: 将当前业务层对象存入spring容器中
4.@Repository: 将当前持久层对象存入spring容器中
以上三个与component一样!
例子:

@Component
public class AccountServiceImpl implements IAccountService{
}
//main文件
//1.获取核心容器对象,此方法构建容器时,对象立即加载,用的多!
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
//2.根据id获取bean对象
IAccountService as =(IAccountService) ac.getBean("accountService");
用于注入对象的注解

相当于bean标签的<property>标签
1.@Autowired: 自动按照成员变量类型注入.
注入过程
当spring容器中有且只有一个对象的类型与要注入的类型相同时,注入该对象.
当spring容器中有多个对象类型与要注入的类型相同时,使用要注入的变量名作为bean的id,在spring 容器查找,找到则注入该对象.找不到则报错.
出现位置: 既可以在变量上,也可以在方法上
细节: 使用注解注入时,set方法可以省略
2.@Qualifier: 在自动按照类型注入的基础之上,再按照bean的id注入.
出现位置: 既可以在变量上,也可以在方法上.注入变量时不能独立使用,必须和@Autowire一起使用; 注入方法时可以独立使用.
属性:
value: 指定bean的id
3.@Resource: 直接按照bean的id注入,它可以独立使用.独立使用时相当于同时使用@Autowired@Qualifier两个注解.
属性:
name: 指定bean的id
4.@Value: 注入基本数据类型和String类型数据
属性:
value: 用于指定数据的值,可以使用el表达式(${表达式})

用于改变作用范围的注解

这些注解的作用相当于bean.xml中的标签的scope属性.
@Scope: 指定bean的作用范围
属性:
value: 用于指定作用范围的取值,“singleton”,“prototype”,“request”,“session”,“globalsession”

和生命周期相关的注解

这些注解的作用相当于bean.xml中的标签的init-method和destroy-method属性
@PostConstruct: 用于指定初始化方法
@PreDestroy: 用于指定销毁方法

实例(基于XML的IOC案例)

1.创建数据库

 create table account(
 	id int primary key auto_increment,
 	name varchar(40),
 	money float
 )character set utf8 collate utf8_general_ci;
 insert into account(name,money) values('aaa',1000);
 insert into account(name,money) values('bbb',1000);
 insert into account(name,money) values('ccc',1000);

2.文件结构
文件结构
3.接口代码
IAccountDao

  public interface IAccountDao {
  
      /**
       * 查询所有
       * @return
       */
      List<Account> findAllAccount();
  
      /**
       * 查询一个
       * @return
       */
      Account findAccountById(Integer accountId);
  
      /**
       * 保存
       * @param account
       */
      void saveAccount(Account account);
  
      /**
       * 更新
       * @param account
       */
      void updateAccount(Account account);
  
      /**
       * 删除
       * @param accountId
       */
      void deleteAccount(Integer accountId);
  }

IAccountService

  public interface IAccountService {
  
      /**
       * 查询所有
       * @return
       */
      List<Account> findAllAccount();
  
      /**
       * 查询一个
       * @return
       */
      Account findAccountById(Integer accountId);
  
      /**
       * 保存
       * @param account
       */
      void saveAccount(Account account);
  
      /**
       * 更新
       * @param account
       */
      void updateAccount(Account account);
  
      /**
       * 删除
       * @param accountId
       */
      void deleteAccount(Integer accountId);
  }

4.实现类代码
AccountDaoImpl

  public class AccountDaoImpl implements IAccountDao {
  
      private QueryRunner runner;
  
      public void setRunner(QueryRunner runner) {
          this.runner = runner;
      }
  
      public List<Account> findAllAccount() {
          try{
              return runner.query("select * from account", new BeanListHandler<Account>(Account.class));
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  
      public Account findAccountById(Integer accountId) {
          try{
              return runner.query("select * from account where id = ?", new BeanHandler<Account>(Account.class),accountId);
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  
      public void saveAccount(Account account) {
          try{
              runner.update("insert into account(name, money) values(?,?)", account.getName(),account.getMoney());
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  
      public void updateAccount(Account account) {
          try{
              runner.update("update account set name = ?, money = ? where id = ?", account.getName(),account.getMoney(),account.getId());
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  
      public void deleteAccount(Integer accountId) {
          try{
              runner.update("delete from account where id = ?", accountId);
          } catch (Exception e) {
              throw new RuntimeException(e);
          }

AccountServiceImpl

  public class AccountServiceImpl implements IAccountService {
  
      private IAccountDao accountDao;
  
      public void setAccountDao(IAccountDao accountDao) {
          this.accountDao = accountDao;
      }
  
      public List<Account> findAllAccount() {
          return accountDao.findAllAccount();
      }
  
      public Account findAccountById(Integer accountId) {
          return accountDao.findAccountById(accountId);
      }
  
      public void saveAccount(Account account) {
          accountDao.saveAccount(account);
      }
  
      public void updateAccount(Account account) {
          accountDao.updateAccount(account);
      }
  
      public void deleteAccount(Integer accountId) {
          accountDao.deleteAccount(accountId);
      }
  }

5.账户实体类
Account

  public class Account implements Serializable {
  
      private Integer id;
      private String name;
      private Float money;
  
      public void setId(Integer id) {
          this.id = id;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public void setMoney(Float money) {
          this.money = money;
      }
  
      public Integer getId() {
          return id;
      }
  
      public String getName() {
          return name;
      }
  
      public Float getMoney() {
          return money;
      }
  
      @Override
      public String toString() {
          return "Account{" +
                  "id=" + id +
                  ", name='" + name + '\'' +
                  ", money=" + money +
                  '}';
      }
  }

6.测试类代码
AccountServiceTest

public class AccountServiceTest {
  
      @Test
      public void testFindAll() {
          // 1.获取容器
          ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
          // 2.得到业务层对象
          IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
          // 3.执行方法
          List<Account> accounts = iAccountService.findAllAccount();
          for (Account account : accounts) {
              System.out.println(account);
          }
      }
  
      @Test
      public void testFindOne() {
          // 1.获取容器
          ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
          // 2.得到业务层对象
          IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
          // 3.执行方法
          Account account = iAccountService.findAccountById(1);
          System.out.println(account);
      }
  
      @Test
      public void testSave() {
          Account account = new Account();
          account.setName("test");
          account.setMoney(12345f);
          // 1.获取容器
          ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
          // 2.得到业务层对象
          IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
          // 3.执行方法
          iAccountService.saveAccount(account);
      }
  
      @Test
      public void testUpdate() {
          // 1.获取容器
          ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
          // 2.得到业务层对象
          IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
          // 3.执行方法
          Account account = iAccountService.findAccountById(4);
          account.setMoney(23456f);
          iAccountService.updateAccount(account);
      }
  
      @Test
      public void testDelete() {
          // 1.获取容器
          ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
          // 2.得到业务层对象
          IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
          // 3.执行方法
          iAccountService.deleteAccount(4);
      }
  }

bean.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
       <!-- -->
      <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
          <property name="accountdao" ref="accountDao"></property>
      </bean>

    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
        <property name="runner" ref="runner"></property>
    </bean>

    <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="123456"></property>
    </bean>
 
</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值