欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring03_基于注解的IOC配置、IOC 案例

程序员文章站 2024-01-03 09:07:52
...

第四章: 基于注解的IOC配置

注解配置 和 xml配置要实现的功能都是一样的,都是要降低程序之间的耦合,只是配置形式不一样

步骤:

第一步:在配置文件(bean.xml)中找到注解的位置:

使用注解进行开发,还需多一个AOP的jar包

配置文件:

​ 导入的约束:在官网上找(使用的约束和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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 告知spring要扫描的包 ,配置所需的标签不是在beans约束中,而是在一个名称为context名称空间和约束中-->
    <!-- 使用的约束和xml配置使用的约束不一样-->
    <!-- 会找到该包进行扫描,找到对应的注解-->
    <!-- base-package导入包的位置-->
    <context:component-scan base-package="com.zy"/>

</beans>

第二步:在类上进行注解的定义

<!-- 曾经XML的配置: -->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"  scope=""  init-method="" destroy-method="">
     <property name="get方法"  value="" | ref=""></property>
</bean>

(1)创建Bean对象放到容器中的注解:

  • 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的

  • @Component:
         作用:用于把当前类对象存入spring容器中(是一下三个注解的父类)(默认调用该方法的构造方法创建)
         属性:             
    		  value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
         出现的位置: 在类上添加该注解
         使用方法:
             	1:  在类上加  @Component   类的名称为id值(首字母字母小写)
             	2:	在类上加  @Component(value="id值")  
             	3:  在类上加  @Component("id值")    使用于只有一个值的情况下
    
  • @Controller:   一般用在表现层
    	作用:是@Component注解的子标签,和其一样的作用,只不过是该标签常用于表现层
    	出现的位置: 在类上添加该注解
    
  • @Service:		一般用在业务层
    作用:是@Component注解的子标签,和其一样的作用,只不过是该标签常用于表现层
    出现的位置: 在类上添加该注解
    
  • @Repository :	一般用在持久层
    作用:是@Component注解的子标签,和其一样的作用,只不过是该标签常用于表现层
    出现的位置: 在类上添加该注解
    

(2) 用于注入数据的注解:

  • 他们的作用和xml配置中的标签一样

  • Bean类型的注入
    • @Autowired:
           作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
                 如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
               	(告诉mybatis这个Bean属性是调用的哪个对象,mybatis会取容器中自己找该对象(mybatis先找,先根据类名找,先根据接口找,在根据属性名找))
                 如果Ioc容器中有多个类型匹配时:
           出现位置:
                 可以是变量上,也可以是方法上
           细节:
                 在使用注解注入时,set方法就不是必须的了。
           补充:
               	@Autowired@Autowired(required=true)   不允许该属性为空(默认值)(容器中必须有该对象)
                @Autowired(required=false)   允许该属性为空(容器中可以没有该属性的Bean对象)
      
      • mybatis根据提供的@Autowired标签找容器中的对象??(自动注入)

        • 比如: 在一个成员变量(Bean变量)上面声明了 @Autowired

        • 现在容器中有一下三个bean对象:

        • 先根据IAccountDao接口找容器中的对象,找到两个实现类对象(AcountDao1 和 AcountDao2),在根据属性名找值,唯一确定的是AccountDao1的对象

Spring03_基于注解的IOC配置、IOC 案例

  - 下面代码:

    - ```java
      @Controller("dao")
      public class AccountDao implements IAccountDao {
         public AccountDao() {
         }
         public void saveAccount() {
            System.out.println("账户已保存");
         }
      }
      --------------------------------------------------------------------------------------------------------
      @Controller("service")
      public class AccountService implements IAccountService {
      	@Autowired
      	private final IAccountDao accountDao = null;
      
      	public IAccountDao getAccountDao() {
      		return accountDao;
      	}
      
      	public void saveAccountService() {
      		accountDao.saveAccount();
      	}
      }
      -----------------------------------------------------------------------------------------------------------
      测试类:
      public class text {
      	public static void main(String[] args) {
      		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
      		AccountDao accountDao = (AccountDao)applicationContext.getBean("dao");
      		System.out.println(accountDao);
      		AccountService accountService = (AccountService)applicationContext.getBean("service");
      		System.out.println(accountService);
      		System.out.println(accountService.getAccountDao());
      	}
      }
      ------------------------------------------------------------------------------------------------------------
       运行结果:
          aaa@qq.com
      	aaa@qq.com
      	aaa@qq.com
          可以发现,accountService中的accountDao,就是容器中的AccountDao的Bean对象
          AccountService类的AccountDao属性在标记上@Autowired的时候,自动在容器中获取对象
      ```
  • @Qualifier:
          作用:
              在按照类型注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以(稍后我们讲)
              (该属性要使用容器中的对象:利用id实现指定)
              	解决@Autowired的缺陷
          出现的位置:
               可以是变量上,也可以是方法上
          属性:
              value:用于指定注入bean的id。
          注意:
              在给类成员变量的时候,不能单独使用,要配合@Autowired
              在给方法配置的时候,可以单独使用
    
  • public class AccountDao implements IAccountDao {
    	public AccountDao() {
    	}
    	public void saveAccount() {
    		System.out.println("账户已保存");
    	}
    }
    ------------------------------------------------------------------------------------------
    在容器中创建了两个AccountDao的对象
    <bean id="dao1" class="com.zy.dao.impl.AccountDao"/>
    <bean id="dao2" class="com.zy.dao.impl.AccountDao"/>
    -----------------------------------------------------------------------------------------
    @Controller("service")
    public class AccountService implements IAccountService {
    	//指定出该属性要使用容器中的哪一个AcountDao对象(使用dao1)
    	@Autowired
    	@Qualifier(value = "dao1")
    	private final IAccountDao accountDao = null;
    
    	public IAccountDao getAccountDao() {
    		return accountDao;
    	}
    
    	public void saveAccountService() {
    		accountDao.saveAccount();
    	}
    }
    ------------------------------------------------------------------------------------------
    测试:
    public class text {
    	public static void main(String[] args) {
    		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    		AccountDao accountDao1 = (AccountDao)applicationContext.getBean("dao1");
    		AccountDao accountDao2 = (AccountDao)applicationContext.getBean("dao2");
    		System.out.println(accountDao1);
    		System.out.println(accountDao2);
    		AccountService accountService = (AccountService)applicationContext.getBean("service");
    		System.out.println(accountService);
    		System.out.println(accountService.getAccountDao());
    	}
    }
    ---------------------------------------------------------------------------------------------
    运行结果:
    com.zy.dao.impl.AccountDao@71d15f18
    com.zy.dao.impl.AccountDao@17695df3
    com.zy.serivce.impl.AccountService@6c9f5c0d
    com.zy.dao.impl.AccountDao@71d15f18
    容器中的AccountService对象使用的是AccountDao的dao1对象
    
  • @Resource
          作用:
              直接按照bean的id注入。它可以独立使用
              (在使用@Qualifier指定成员变量的时候,还需要用@Autowired太过于麻烦,直接用该标签进行代替)
          出现的位置:
              方法和属性上
          属性:
               name:用于指定bean的id。(相当于@Qualifier中的value的值)
    
  • 注意:

    • 以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
    • 另外,集合类型的注入只能通过XML来实现
  • 基本类型的注入
  • @Value
    	   作用:
               用于注入基本类型和String类型的数据
            出现的位置:
               基本类型的成员变量上
            属性:
            	value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
                SpEL的写法:${表达式}  
    

(3) 用于改变作用范围的

  • 他们的作用就和<bean>上的scope属性一样

    • @Scope
            作用:用于指定bean的作用范围
            出现位置:类上
            属性:
               value:指定范围的取值。常用取值:singleton(单例)   prototype(多例)
      

(4) 和生命周期相关的注解

  • 他们的作用就和在<bean>中使用init-method属性和destroy-methode属性的作用是一样的

    • @PreDestroy
          作用:
              	用于指定销毁方法
          使用的位置:
              	在方法上出现
      @PostConstruct
          作用:
              	用于指定初始化方法
          使用的位置:
              	在方法上出现
      




案例: 基于xml文件的IOC案例

Spring03_基于注解的IOC配置、IOC 案例

代码:

------------------------------------------------------------------------------------------------------------------------------------
domain中的实体类
public class Account implements Serializable {

    private Integer id;
    private String name;
    private Float money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Float getMoney() {
        return money;
    }

    public void setMoney(Float money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}
--------------------------------------------------------------------------------------------------------------------------------
Dao持久层:
    

/**
 * 账户的持久层接口
 */
public interface IAccountDao {
    // 查询所有
    List<Account> findAllAccount();
    // 查询一个
    Account findAccountById(Integer accountId);
    // 保存
    void saveAccount(Account account);
    //更新
    void updateAccount(Account account);
    // 删除
    void deleteAccount(Integer acccountId);
}


/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl implements IAccountDao {
    //需要一个QueryRunner对象
    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);
        }
    }
}
----------------------------------------------------------------------------------------------------------------------------
 Service业务层:


/**
 * 账户的业务层接口
 */
public interface IAccountService {
    // 查询所有
    List<Account> findAllAccount();
    // 查询一个
    Account findAccountById(Integer accountId);
    // 保存
    void saveAccount(Account account);
    //更新
    void updateAccount(Account account);
    // 删除
    void deleteAccount(Integer acccountId);
}


/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements IAccountService{
    //需要一个IAccountDao的实现类对象
    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 acccountId) {
        accountDao.deleteAccount(acccountId);
    }
}

---------------------------------------------------------------------------------------------------------------------
    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
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 配置Service -->
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
        <!-- 注入dao -->
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!--配置Dao对象-->
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
        <!-- 注入QueryRunner -->
        <property name="runner" ref="runner"></property>
    </bean>

    <!--配置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.cj.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis_damo1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false"></property>
        <property name="user" value="root"></property>
        <property name="password" value="015718"></property>
    </bean>
</beans>

案例: 基于注解的IOC案例

Spring03_基于注解的IOC配置、IOC 案例

---------------------------------------------------------------------------------------------------------------------------------------
dao包:
/**
 * 账户的实体类
 */
public class Account implements Serializable {

    private Integer id;
    private String name;
    private Float money;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Float getMoney() {
        return money;
    }
    public void setMoney(Float money) {
        this.money = money;
    }
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}
----------------------------------------------------------------------------------------------------------------------------------------
Dao持久层:
    
/**
 * 账户的持久层接口
 */
public interface IAccountDao {
    // 查询所有
    List<Account> findAllAccount();
    // 查询一个
    Account findAccountById(Integer accountId);
    // 保存
    void saveAccount(Account account);
    //更新
    void updateAccount(Account account);
    // 删除
    void deleteAccount(Integer acccountId);
}

/**
 * 账户的持久层实现类
 */
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {

    @Autowired
    private QueryRunner 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);
        }
    }
}
----------------------------------------------------------------------------------------------------------------------------------------
Service业务层:

/**
 * 账户的业务层接口
 */
public interface IAccountService {
    // 查询所有
    List<Account> findAllAccount();
    // 查询一个
    Account findAccountById(Integer accountId);
    // 保存
    void saveAccount(Account account);
    //更新
    void updateAccount(Account account);
    // 删除
    void deleteAccount(Integer acccountId);
}


/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements IAccountService{
    //需要一个IAccountDao的实现类对象
     @Autowired
    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 acccountId) {
        accountDao.deleteAccount(acccountId);
    }
}
----------------------------------------------------------------------------------------------------------------------------------------
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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 告知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.cj.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis_damo1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false"></property>
        <property name="user" value="root"></property>
        <property name="password" value="015718"></property>
    </bean>
</beans>
----------------------------------------------------------------------------------------------------------------------------------------
  在Dao接口的实现类上和Service接口的实现类上 ,其相应的成员变量添加上@Autowirde,在配置文件中只需要配置QueryRunner和ComboPooledDataSource对象
相关标签: Spring spring

上一篇:

下一篇: