zoukankan      html  css  js  c++  java
  • Spring框架学习日志(2/4)

    Spring框架第二天

     
    1、使用注解完成IOC
    (注意:这个是 注解 + XML 配置的,并没有完全摆脱XML)
     
    首先,修改配置文件约束,这是用注解配置IOC时的约束,类似于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
            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在创建容器时要扫描的包,这时Spring才能知道是注解配置的项目
    <context:component-scan base-package="com.cjf"></context:component-scan>
     
     
    @Component 该注解的作用:
    <bean id="accountService"class="com.cjf.service.impl.AccountServiceImpl">
    </bean>
    @Component("accountService")
    public class AccountServiceImpl implements IAccountService {
    }
     
    @Controller:表现层
    @Service:业务层
    @Repository:持久层
     
     
    @Autowired 该注解的作用:直接按照数据类型IAccountDao匹配实现类AccountDaoImpl,
    如果存在多个实现类,则按照名字匹配,如果名字也不一样,就报错
    (可以去掉set方法了)
    <bean id="accountService2" class="com.cjf.service.impl.AccountServiceImpl2">
        <property name="birthday" ref="date"></property>
    </bean>
     
    <bean id="date" class="java.util.Date"></bean>
    @Autowired
    private IAccountDao accountDao;//三个都只能注入Bean类型
     
     
    @Autowired
    @Qualifier("accountDao1")//配合使用
     
     
    @Resource(name="accountDao1")//直接使用
     
     
    @Scope 该注解的作用:
    @Scope("singleton")//单例
    @Scope("prototype")//多例
     
     
    @ 生命周期了解
     
     
    2、案例IOC(基于XML,持久层使用dbutils技术)
    1. 导入坐标依赖
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</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>
            <scope>test</scope>
        </dependency>
    </dependencies>
     
    2、准备:Account实体类
    持久层实现类:
    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 (SQLException e) {
                throw new RuntimeException(e);
            }
        }
     
     
        public Account findAccountById(Integer id) {
            try {
                return runner.query("select * from account where id= ?",new BeanHandler<Account>(Account.class),id);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
     
     
        public void saveAccount(Account account) {
            try {
                runner.update("insert into account(name,money)values (?,?)",account.getName(),account.getMoney());
            } catch (SQLException 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 (SQLException e) {
                throw new RuntimeException(e);
            }
        }
     
     
        public void deleteAccount(Integer id) {
            try {
                runner.update("delete from account where id = ?",id);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
     
    业务层实现类:
    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 id) {
            return accountDao.findAccountById(id);
        }
     
     
        public void saveAccount(Account account) {
            accountDao.saveAccount(account);
        }
     
     
        public void updateAccount(Account account) {
            accountDao.updateAccount(account);
        }
     
     
        public void deleteAccount(Integer id) {
            accountDao.deleteAccount(id);
        }
    }
     
     
    配置文件bean.xml
    <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">
     
     
            <!--配置Service-->
        <bean id="accountService" class="com.cjf.service.impl.AccountServiceImpl">
            <!--注入dao-->
            <property name="accountDao" ref="accountDao"></property>
        </bean>
     
     
        <!--配置dao对象-->
        <bean id="accountDao" class="com.cjf.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.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>
     
     
    测试方法(模拟表现层)
    @Test
    public void testFindAll(){
        //1、获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
     
        //2.得到业务层对象
        IAccountService as = (IAccountService) ac.getBean("accountService");
     
        //3、执行方法
        List<Account> accounts = as.findAllAccount();
        for(Account account : accounts){
            System.out.println(account);
        }
    }
     
     
    3、案例IOC(基于注解,持久层使用dbutils技术)
    1.配置文件约束使用注解的约束
    <?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
            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在创建容器时要扫描的包,
            配置所需要的标签不是在beans的约束中,
            而是一个名称为context名称空间和约束中
        -->
        <context:component-scan base-package="com.cjf"></context:component-scan>
     
    </beans>
     
     
    2.改造持久层的实现类
    将创建javabean的xml改为使用注解@Repository("accountDao")
    注入的依赖改为使用注解@Autowired,可以去掉set方法
    @Repository("accountDao")
    public class AccountDaoImpl implements IAccountDao {
     
     
        @Autowired
        private QueryRunner runner;
     
     
        public QueryRunner getRunner() {
            return runner;
        }
     
     
        public List<Account> findAllAccount() {
            try {
                return runner.query("select * from account",new BeanListHandler<Account>(Account.class));
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
     
     
        public Account findAccountById(Integer id) {
            try {
                return runner.query("select * from account where id= ?",new BeanHandler<Account>(Account.class),id);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
     
     
        public void saveAccount(Account account) {
            try {
                runner.update("insert into account(name,money)values (?,?)",account.getName(),account.getMoney());
            } catch (SQLException 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 (SQLException e) {
                throw new RuntimeException(e);
            }
     
     
        }
     
     
        public void deleteAccount(Integer id) {
            try {
                runner.update("delete from account where id = ?",id);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
     
     
        }
    }
     
     
    3、改造业务层的实现类
    将创建javabean的xml改为使用注解
    注入的依赖改为使用注解
    @Service("accountService")
    public class AccountServiceImpl implements IAccountService {
     
     
        @Autowired
        private IAccountDao accountDao;
        //有了Autowired就可以去掉set方法
     
     
        public List<Account> findAllAccount() {
            return accountDao.findAllAccount();
        }
     
     
        public Account findAccountById(Integer id) {
            return accountDao.findAccountById(id);
        }
     
     
        public void saveAccount(Account account) {
            accountDao.saveAccount(account);
        }
     
     
        public void updateAccount(Account account) {
            accountDao.updateAccount(account);
        }
     
     
        public void deleteAccount(Integer id) {
            accountDao.deleteAccount(id);
        }
    }
     
     
     
    4.完全摆脱XML,使用新注解完成纯注解开发
    既然是注解替换XML开发,必然要在代码中完成XML文件的替换
    所以创建Config包下的SpringConfiguration类
     
    1、使用@Configuration替换XML文件的约束,代表是一个配置文件
    2、使用@ComponentScan(basePackages = {"com.cjf"}),代替XML配置
    <context:component-scan base-package="com.cjf"></context:component-scan>
    3、@Bean
            作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
            属性:
                    name:用于指定bean的id,不写时,默认值是当前方法的名称
            细节:
                    当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。查找的方式和Autowired注解的作用是一样的
     
    @Configuration
    @ComponentScan(basePackages = {"com.cjf"})
    @PropertySource("classpath:jdbcConfig.properties")
    public class SpringConfiguration {
     
     
     
        @Value("${jdbc.driver}")
        private String driver;
     
     
        @Value("${jdbc.url}")
        private String url;
     
     
        @Value("${jdbc.user}")
        private String username;
     
     
        @Value("${jdbc.password}")
        private String password;
     
     
     
     
        /*
           用于创建一个QueryRunner对象
         */
        @Bean(name = "runner")
        @Scope("prototype")
        public QueryRunner createQueryRunner(DataSource dataSource) {
            return new QueryRunner(dataSource);
        }
     
     
     
     
        /*
            用于创建数据源对象
         */
        @Bean(name = "dataSource")
        public DataSource createDataSource() {
            try {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(driver);
                ds.setJdbcUrl(url);
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
     
    5.改用AnnotationConfigApplicationContext实例化测试类的容器
    ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class)
     
    6.QueryRunner对象改为多例
    /*
           用于创建一个QueryRunner对象
         */
        @Bean(name = "runner")
        @Scope("prototype")
        public QueryRunner createQueryRunner(DataSource dataSource) {
            return new QueryRunner(dataSource);
        }
     
    7.@Configuration可以不写的情况
    当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写,参数可以添加多个
    ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class)
     
    7.@import注解
    @import
            作用:用于导入其他的配置类
            属性:
                    value:用于指定其他配置类的字节码
     
    @Import("JdbcConfig.class")
     
                    当我们使用import的注解之后,有import注解的类就父配置类,而导入的都是子配置类
     
    7.使用jdbcConfig.properties
     
    jdbc.driver = com.mysql.jdbc.Driver
    jdbc.url = jdbc:mysql://localhost:3306/eesy
    jdbc.user = root
    jdbc.password = 123456
     
     
    8.@PropertySource
    @PropertiesSource
           作用:用于指定properties文件的位置
           属性:
                                    value:指定文件的名字和路径
           关键字:classpath,表示类路径下
    @PropertySource("classpath:jdbcConfig.properties")
     
        @Value("${jdbc.driver}")
        private String driver;
     
     
        @Value("${jdbc.url}")
        private String url;
     
     
        @Value("${jdbc.user}")
        private String username;
     
     
        @Value("${jdbc.password}")
        private String password;
     
     
         /*
            用于创建数据源对象
         */
        @Bean(name = "dataSource")
        public DataSource createDataSource() {
            try {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(driver);
                ds.setJdbcUrl(url);
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
     
    8.如果使用不同的数据源,即有两个dataSource的情况下,可以使用代码内部添加注解@Qualifier("dataSource")的方式指定想要的数据源
     
    @Bean(name = "runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(@Qualifier("dataSource") DataSource dataSource) {
        return new QueryRunner(dataSource);
    }
     
    9.使用Junit单元测试:测试我们的配置
    使用junit单元测试
    Spring整合junit的配置:
                1、导入spring整合junit的jar坐标(依赖)
                 2、使用junit提供的一个注解把原有的main方法替换了,替换成Spring的提供的
     @Runwith
                 3、告知Spring的运行器,spring和ioc创建是基于xmL还是注解的,并且说明位置
     @ContextConfiguration
                     location:指定xmL文件的位置,加上classpath关键字,表示在类路径下
                     classes:指定注解类所在的位置
     
    导入test依赖
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
     
     
    使用@ContextConfiguration(classes = SpringConfiguration.class)代替
    获得容器的语句
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfiguration.class)
    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(){
            //3、执行方法
            Account account = new Account();
            account.setId(4);
            account.setMoney(10000);
            account.setName("ddd");
            as.saveAccount(account);
            System.out.println(account);
        }
     
     
     
        @Test
        public void testUpdate(){
            //3、执行方法
            Account account = as.findAccountById(1);
            account.setName("AAA");
            as.updateAccount(account);
        }
     
     
     
        @Test
        public void testDelete(){
            //3、执行方法
            as.deleteAccount(4);
        }
    }
     
     
     
     
  • 相关阅读:
    Mybatis(二)入门程序通过id查找用户、模糊查找用户、添加用户、删除用户
    excel测试数据导入
    (转)接口自动化测试之http请求实践总结
    (转)TestNG框架提供两种传入参数的方法:
    Jmeter 集成Excel读写接口参数返回值
    优化问题
    redux
    clientHeight offsetTop scrollTop
    antddesign
    ACMICPC实验室周赛2020.3.6
  • 原文地址:https://www.cnblogs.com/cuijunfeng/p/13670095.html
Copyright © 2011-2022 走看看