原来的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 https://www.springframework.org/schema/context/spring-context.xsd"> <!--配置QueryRunner对象--> <bean id="queryRunner" 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_ser?serverTimezone=UTC"></property> <property name="user" value="root"></property> <property name="password" value="123456"></property> </bean> </beans>
配置类如下:
package com.jh.config; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.apache.commons.dbutils.QueryRunner; import org.springframework.context.annotation.*; import javax.sql.DataSource; import java.beans.PropertyVetoException; /** * 该类时一个配置类,它的作用和bean.xml是一样的 * spring中的新注解 * Configuration * 作用:指定当前类是一个配置类 * ComponentScan * 作用:用于通过注解指定spring在创建容器时要扫描的包 * 属性: * value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包 * 我们使用此注解就等同于在xml中配置了: * <context:component-scan base-package="com.jh"></context:component-scan> * Bean * 作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中 * 属性: * name:用于指定bean的id.当不写时,默认值是当前方法的名称 * 细节: * 当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。 * 查找的方式和Autowired注解的作用是一样的 */ @Configuration @ComponentScan(basePackages = "com.jh") public class SpringConfiguration { /** * 用于创建一个QueryRunner对象 * @param dataSource * @return */ @Bean(name = "queryRunner") @Scope("prototype") public QueryRunner createQueryRunner(DataSource dataSource){ return new QueryRunner(dataSource); } /** * 创建数据源对象 * @return */ @Bean(name = "dataSource") public DataSource createDataSource(){ ComboPooledDataSource ds = new ComboPooledDataSource(); try { ds.setDriverClass("com.mysql.cj.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis_ser?serverTimezone=UTC"); ds.setUser("root"); ds.setPassword("123456"); } catch (PropertyVetoException e) { e.printStackTrace(); } return ds; } }
给出一个小问题:以下两张图代码是否作用相同?
答案:不相同,因为 spring的IOC 容器其实可以看成 Map<key,value> 对象,第二种可以存入到 spring 容器中,第一种只是一个方法,不会存入到 spring 容器 中。所以需要 @Bean 注解,将方法的返回值作为 bean 对象存入到 spring 的 ioc 容器中。如果第一种用了 @Bean 注解,作用和第二种一样。
测试类:
package com.jh.test; import com.jh.config.SpringConfiguration; import com.jh.entity.Account; import com.jh.service.AccountService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class AccountTest { @Test public void TestFindAllAccount() { //加载spring配置文件,创建spring上下文对象 ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class); //获取accountService对象 AccountService accountService = (AccountService) ac.getBean("accountService");
//第二种创建acountService对象的方式
AccountService accountService = ac.getBean("accountService",AccountService.class); List<Account> list = accountService.findAllAccount(); for (Account a : list) { System.out.println(a); } } }
最后补充一个QueryRunner
package com.jh.dao.impl; import com.jh.dao.AccountDao; import com.jh.entity.Account; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.sql.SQLException; import java.util.List; @Repository("accountDao") public class AccountDaoImpl implements AccountDao { @Autowired private QueryRunner queryRunner; public List<Account> findAllAccount() { try { return queryRunner.query("select * from account", new BeanListHandler<Account>(Account.class)); } catch (SQLException throwables) { throw new RuntimeException(throwables); } } public Account findAccountById(Integer id) { try { return queryRunner.query("select * from account where id=?", new BeanHandler<Account>(Account.class),id); } catch (SQLException throwables) { throw new RuntimeException(throwables); } } public void insertOne(Account account) { try { queryRunner.update("insert into account(name,money) values(?,?)", account.getName(), account.getMoney()); } catch (SQLException throwables) { throw new RuntimeException(throwables); } } public void deleteOne(Integer id) { try { queryRunner.update("delete from account where id=?", id); } catch (SQLException throwables) { throw new RuntimeException(throwables); } } public void updateOne(Account account) { try { queryRunner.update("update account set name=?,money=? where id=?", account.getName(), account.getMoney(), account.getId()); } catch (SQLException throwables) { throw new RuntimeException(throwables); } } }