spring基于注解的IOC(2)

spring第二天:spring基于注解的IOC以及IoC的案例
1、spring中ioc的常用注解

用于创建对象的:Component、Controller、Service、Repository

用于注入数据的:Autowired、Qualifier、Resource、Value

用于改变作用范围的:Scope 、

和生命周期相关:PreDestroy 、PostConstruct

2、案例使用xml方式和注解方式实现单表的CRUD操作
 持久层技术选择:dbutils
3、改造基于注解的ioc案例,使用纯注解的方式实现
 spring的一些新注解使用
4、spring和Junit整合



一、spring中基于ioc的常用注解

/**
 * 账户的业务层实现类
 *
 * 曾经XML的配置:
 *  <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
 *        scope=""  init-method="" destroy-method="">
 *      <property name=""  value="" | ref=""></property>
 *  </bean>
 *
 * 用于创建对象的
 *      他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的
 *      Component:
 *          作用:用于把当前类对象存入spring容器中
 *          属性:
 *              value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
 *      Controller:一般用在表现层
 *      Service:一般用在业务层
 *      Repository:一般用在持久层
 *      以上三个注解他们的作用和属性与Component是一模一样。
 *      他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰
 *
 *
 * 用于注入数据的
 *      他们的作用就和在xml配置文件中的bean标签中写一个<property>标签的作用是一样的
 *      Autowired:
 *          作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
 *                如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
 *                如果Ioc容器中有多个类型匹配时:
 *          出现位置:
 *              可以是变量上,也可以是方法上
 *          细节:
 *              在使用注解注入时,set方法就不是必须的了。
 *      Qualifier:
 *          作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以(稍后我们讲)
 *          属性:
 *              value:用于指定注入bean的id。
 *      Resource
 *          作用:直接按照bean的id注入。它可以独立使用
 *          属性:
 *              name:用于指定bean的id。
 *      以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
 *      另外,集合类型的注入只能通过XML来实现。
 *
 *      Value
 *          作用:用于注入基本类型和String类型的数据
 *          属性:
 *              value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
 *                      SpEL的写法:${表达式}
 *
 * 用于改变作用范围的
 *      他们的作用就和在bean标签中使用scope属性实现的功能是一样的
 *      Scope
 *          作用:用于指定bean的作用范围
 *          属性:
 *              value:指定范围的取值。常用取值:singleton prototype
 *
 * 和生命周期相关 了解
 *      他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的
 *      PreDestroy
 *          作用:用于指定销毁方法
 *      PostConstruct
 *          作用:用于指定初始化方法
 */

1. 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在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为
    context名称空间和约束中-->
    <context:component-scan base-package="com.itheima"></context:component-scan>
</beans>

2.自动按照类型注入

原理图

2.代码演示

 Qualifier: *          作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以(稍后我们讲) *          属性: *              value:用于指定注入bean的id。 Resource *          作用:直接按照bean的id注入。它可以独立使用 *          属性: *              name:用于指定bean的id。 *      以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。 *      另外,集合类型的注入只能通过XML来实现。 *

//    @Autowired
//    @Qualifier("accountDao1")
    @Resource(name = "accountDao2")
    private IAccountDao accountDao = null;
 *      Value
 *          作用:用于注入基本类型和String类型的数据
 *          属性:
 *              value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
 *                      SpEL的写法:${表达式}

用于改变作用范围的注解

@Service("accountService")
//@Scope("prototype")
public class AccountServiceImpl implements IAccountService {

生命周期有关的注解

    @PostConstruct
    public void  init(){
        System.out.println("初始化方法执行了");
    }

    @PreDestroy
    public void  destroy(){
        System.out.println("销毁方法执行了");
    }
/**
 * 模拟一个表现层,用于调用业务层
 */
public class Client {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //1.获取核心容器对象
//        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.根据id获取Bean对象
        IAccountService as  = (IAccountService)ac.getBean("accountService");
//        IAccountService as2  = (IAccountService)ac.getBean("accountService");
//        System.out.println(as);
//        IAccountDao adao = ac.getBean("accountDao",IAccountDao.class);
//        System.out.println(adao);
//        System.out.println(as == as2);
        as.saveAccount();
        ac.close();
    }


二、案例使用xml方式和注解方式实现单表的CRUD操作

1.引入项目相关的坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>day02_eesy_02account_xmlioc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>

        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>

2.Account实体类

package com.itheima.domain;

import java.io.Serializable;

/**
 * 账户的实体类
 */
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 +
                ‘}‘;
    }
}

3.bean.xml

package com.itheima.domain;

import java.io.Serializable;

/**
 * 账户的实体类
 */
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 +
                ‘}‘;
    }
}

4.接口类 IAccountService、IAccountDao

 /**
     * 查询所有
     * @return
     */
    List<Account> findAllAccount();

    /**
     * 查询一个
     * @return
     */
    Account findAccountById(Integer accountId);

    /**
     * 保存
     * @param account
     */
    void saveAccount(Account account);

    /**
     * 更新
     * @param account
     */
    void updateAccount(Account account);

    /**
     * 删除
     * @param acccountId
     */
    void deleteAccount(Integer acccountId);
package com.itheima.dao;

import com.itheima.domain.Account;

import java.util.List;

/**
 * 账户的持久层接口
 */
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 acccountId
     */
    void deleteAccount(Integer acccountId);
}

5.接口实现类 IAccountServiceImpl、IAccountDaoImpl

package com.itheima.service.impl;

import com.itheima.dao.IAccountDao;
import com.itheima.domain.Account;
import com.itheima.service.IAccountService;

import java.util.List;

/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements IAccountService{

    private IAccountDao accountDao;

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public List<Account> findAllAccount() {
        return accountDao.findAllAccount();
    }

    @Override
    public Account findAccountById(Integer accountId) {
        return accountDao.findAccountById(accountId);
    }

    @Override
    public void saveAccount(Account account) {
        accountDao.saveAccount(account);
    }

    @Override
    public void updateAccount(Account account) {
        accountDao.updateAccount(account);
    }

    @Override
    public void deleteAccount(Integer acccountId) {
        accountDao.deleteAccount(acccountId);
    }
}
package com.itheima.dao.impl;

import com.itheima.dao.IAccountDao;
import com.itheima.domain.Account;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.util.List;

/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl implements IAccountDao {

    private QueryRunner runner;

    public void setRunner(QueryRunner runner) {
        this.runner = runner;
    }

    @Override
    public List<Account> findAllAccount() {
        try{
            return runner.query("select * from account",new BeanListHandler<Account>(Account.class));
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    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);
        }
    }

    @Override
    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);
        }
    }

    @Override
    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);
        }
    }

    @Override
    public void deleteAccount(Integer accountId) {
        try{
            runner.update("delete from account where id=?",accountId);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

6.编写测试类

package com.itheima.test;

import com.itheima.domain.Account;
import com.itheima.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * 使用Junit单元测试:测试我们的配置
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml")
public class AccountServiceTest {

    @Autowired
    private  IAccountService as;

    @Test
    public void testFindAll() {
        //3.执行方法
        List<Account> accounts = as.findAllAccount();
        for(Account account : accounts){
            System.out.println(account);
        }
    }

    @Test
    public void testFindOne() {
        //3.执行方法
        Account account = as.findAccountById(1);
        System.out.println(account);
    }

    @Test
    public void testSave() {
        Account account = new Account();
        account.setName("test");
        account.setMoney(12345f);
        //3.执行方法
        as.saveAccount(account);

    }

    @Test
    public void testUpdate() {
        //3.执行方法
        Account account = as.findAccountById(4);
        account.setMoney(23456f);
        as.updateAccount(account);
    }

    @Test
    public void testDelete() {
        //3.执行方法
        as.deleteAccount(4);
    }
}


三、把自己编写的类使用注解配置 (基于注解的ioc配置)

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.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/eesy"></property>
        <property name="user" value="root"></property>
        <property name="password" value="1234"></property>
    </bean>
</beans>

AccountServiceImpl

/**
 * 账户的业务层实现类
 */
@Service("accountService")
public class AccountServiceImpl implements IAccountService{

    @Autowired
    private IAccountDao accountDao;

AccountDaoImpl

@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {

    @Autowired
    private QueryRunner runner;

原文地址:https://www.cnblogs.com/lsk-130602/p/12207371.html

时间: 2024-10-29 11:37:03

spring基于注解的IOC(2)的相关文章

Spring基于注解TestContext 测试框架使用详解

概述 Spring 2.5 相比于 Spring 2.0 所新增的最重要的功能可以归结为以下 3 点: 1.基于注解的 IoC 功能:  2.基于注解驱动的 Spring MVC 功能:  3.基于注解的 TestContext 测试框架. Spring 推荐开发者使用新的基于注解的 TestContext 测试框架,本文我们将对此进行详细的讲述. 低版本的 Spring 所提供的 Spring 测试框架构在 JUnit 3.8 基础上扩展而来,它提供了若干个测试基类.而 Spring 2.5

结合项目(Spring+(基于注解的)SpringMVC和Mybatis+uploadify文件上传)--poi解析Excel文件

poi解析Excel文件 1.上传文件至服务器 2.解析Excel文件并返回数据集合 3.将数据保存到服务器 框架======Spring+(基于注解的)SpringMVC和Mybatis===== 第一步: 前台: jsp文件采用的是uploadify <div id="fileQueue"></div> <input type="file" id="brandFile"> js: <script ty

阶段3 2.Spring_08.面向切面编程 AOP_9 spring基于注解的AOP配置

复制依赖和改jar包方式 src下的都复制过来. 复制到新项目里了 bean.xml里面复制上面一行代码到下面.把aop改成context. 配置spring容器创建时要扫描的包 Service的配置这里就可以删除了 配置注解 使用@Service注解 开始AOP配置 把通知类交给Spring来管理 在Logger上加注解.之类注意,@Service和@Repository都不合适.因为logger属于三层 所以这里用@Component这个注解来配置 写完上面的@Component的注解后.b

基于注解的Ioc配置 —— Spring(五)

注解配置和Xml配置要实现的功能是一样的,都是要降低程序间的耦合,只是配置的形式不一样. 实际开发中,具体采用注解还是Xml配置,按公司要求. 常用注解: @Component:把资源让Spring来管理,相当于在xml当中配置一个bean. value:指定bean的id,如果不指定value属性,默认bean的id是当前类的类名.首字母小写. @Controller @Service @Repository:都是@Component的衍生注解,作用以及属性都是一样的,只不过提供了更加明确的语

(spring-第4回)spring基于注解的配置

基于XML的bean属性配置:bean的定义信息与bean的实现类是分离的. 基于注解的配置:bean的定义信息是通过在bean实现类上标注注解实现. 也就是说,加了注解,相当于在XML中配置了,一样一样的. 一.举个栗子: 1 package com.mesopotamia.annotation; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class Car { 7 private

spring基于注解和配置源码解读

我们先来建立一个maven项目,引入spring文件,不爱弄的在文章最下面有代码地址可以去下载.先看,后面自己下载代码自己去尝试.先给你们吧,边尝试边看吧. 一.IOC容器注册组件的方式 1. 基础XML注入Bean 是不是超级简单的,我们由浅入深一点点来. 2. 基于注解的方式来配置 我们通过方法名就可以直接得到我们的对象了,默认就是按照方法来装配.也可以通过@Bean(value="newName") 来指定装配的名字. 3. 按照包扫描的方式装配(重点),使用@Component

Spring基于注解@AspectJ的AOP

Spring除了支持XML方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明. 但是用注解方式需要在XML启用对@AspectJ的支持<aop:aspectj-autoproxy/>,将在Spring上下文创建一个AnnotationAwareAspectJAutoProxyCreator类,它会自动代理一些Bean,这些Bean的方法需要与使用@Aspect注解的Bena中所定义的切点相匹配,而这些切点又是使用@Pointcut注解定义出来的,下面来看下例子(PS:我的例子都

从源码分析 Spring 基于注解的事物

在spring引入基于注解的事物(@Transactional)之前,我们一般都是如下这样进行拦截事物的配置: <!-- 拦截器方式配置事物 --> <tx:advice id="transactionAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation=&q

spring基于注解的声明式事务控制配置

配置文件: <?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:aop="http://www.springframework.org/sc