Spring_two
Spring_two
基于注解的IOC配置
准备工作(参考上一篇)
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency></dependencies>
创建接口AccountDao.java
/*** 账户的持久层接口*/public interface AccountDao {/*** 模拟保存账户*/void saveAccount();}
创建实现类AccountDaoImpl.java
/*** 账户的持久层实现类*/public class AccountDaoImpl implements AccountDao {public void saveAccount(){System.out.println("AccountDaoImpl实现了接口AccountDao的保存方法");}}
创建接口AccountService.java
/*** 账户业务层的接口*/public interface AccountService {/*** 模拟保存账户*/void saveAccount();}
创建接口的实现类,AccountServiceImpl.java
public class AccountServiceImpl implements AccountService {//注入private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}public void saveAccount(){accountDao.saveAccount();}}
用applicationContext.xml的方式完成配置(配置文件的IOC和DI)
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl"></bean><bean id="accountService" class="com.it.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean></beans>
测试类
public class Client {public static void main(String[] args) {// 工厂类加载spring的配置文件ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService accountService = ac.getBean("accountService", AccountService.class);accountService.saveAccount();}}
注解配置-控制反转IOC
以前的XML配置
<bean id="accountService" class="com.it.service.impl.AccountServiceImpl" scope="" init-method="" destroy-method=""><property name="" value="" | ref=""></property></bean>
用于创建对象的
他们的作用就和在XML配置文件中编写一个标签实现的功能是一样的
(1)@Component:
- 作用:用于把当前类对象存入spring容器中
- 属性:
value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
(2)Spring中提供了@Component的衍生注解:
- @Controller :用来修饰WEB层类(控制层)(springMVC延用了该注解)
- @Service :用来修饰service层类(业务层)
- @Repository :用来修饰DAO层类(持久层)
以上三个注解他们的作用和属性与Component是一模一样。
他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。
/*** 账户的持久层实现类*/@Repository("accountDao1")//指定以”accountDao1”的ID存入Springpublic class AccountDaoImpl implements AccountDao {public void saveAccount(){System.out.println("AccountDaoImpl实现了接口AccountDao的保存方法");}}
替代了

AccountServiceImpl.java
/*** 账户的业务层实现类*/@Service("accountService1")//指定以”accountService”的ID存入Springpublic class AccountServiceImpl implements AccountService {private AccountDao accountDao = new AccountDaoImpl();public void saveAccount(){accountDao.saveAccount();}}
替代了

applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--注意约束新增了context--><!--告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为context名称空间和约束中--><context:component-scan base-package="com.it"></context:component-scan></beans>
注解配置-依赖注入 DI
用于注入数据的
它们的作用就和在xml配置文件中的bean标签中写一个标签的作用是一样的
@Autowired:
基于spring
作用:
自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
如果Ioc容器中有多个类型匹配时:
先按照类型匹配,如果不能匹配上,会按照属性的名称进行匹配
出现位置:
可以是变量上,也可以是set方法上
细节:
在使用注解注入时,set方法就不是必须的了。
@Qualifier:
配合@Autowired注解一起使用
作用:在按照类型注入的基础之上再按照名称注入。
属性:
value:用于指定注入bean的id。
@Resource
JSR-250标准(基于jdk)
作用:直接按照bean的id名称注入。如果id属性不存在,可以再按照类型注入。它可以独立使用
属性:
name:用于指定bean的id,如果指定name,只能按照bean的id注入,不能按照类型注入。
注意:
以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现(使用@Value)。
@Value
作用:用于注入基本类型和String类型的数据
属性:
value:用于指定数据的值。使用${表达式}可以读取配置文件(.properties文件)的信息
@Value(value = "张三")private String name;@Value(value = "18")private Integer age;public void saveAccount() {System.out.println("执行AccountServiceImpl的保存账号方法 name:"+name+" age:"+age);accountDao.saveAccount();}

@Service("accountService")public class AccountServiceImpl implements AccountService {@Autowired@Qualifier("accountDao1")//@Resource(name = "accountDao2")private AccountDao accountDao;public void saveAccount(){accountDao.saveAccount();}}
替代了

注解配置-作用域
用于改变作用范围的
他们的作用就和在bean标签中使用scope属性实现的功能是一样的
@Scope
作用:用于指定bean的作用范围
属性:
value:指定范围的取值。
常用取值:singleton prototype
@Service("accountService")@Scope("prototype")public class AccountServiceImpl implements AccountService {@Autowired@Qualifier("accountDao1")//@Resource(name = "accountDao2")private AccountDao accountDao = null;public AccountServiceImpl(){System.out.println("构造方法...测试多例");}public void saveAccount(){accountDao.saveAccount();}}

注解配置-初始化和销毁(单例)
配置AccountServiceImpl.java
@Service("accountService")//@Scope("prototype")// 测试初始化和销毁,不能使用多例public class AccountServiceImpl implements AccountService {@Autowired@Qualifier("accountDao1")//@Resource(name = "accountDao2")private AccountDao accountDao = null;public AccountServiceImpl(){System.out.println("构造方法...");}@PostConstructpublic void init(){System.out.println("初始化方法执行了");}@PreDestroypublic void destroy(){System.out.println("销毁方法执行了");}public void saveAccount(){accountDao.saveAccount();}}
等同于配置文件:
<bean id="accountService" class="com.it.service.impl.AccountServiceImpl" init-method=”init” destory-method=”destory”> </bean>
使用spring的IoC的实现账户的CRUD
导入坐标,pom.xml
<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></dependency></dependencies>
创建数据库
create table account(id int primary key auto_increment,name varchar(),money float)character set utf8 collate utf8_general_ci;insert into account(name,money) values('aaa',);insert into account(name,money) values('bbb',);insert into account(name,money) values('ccc',);
创建实体
/*** 账户的实体类*/public class Account implements Serializable {private Integer id;private String name;private Float money;// set和get方法...}
创建接口AccountDao.java
实现CRUD操作
/*** 账户的持久层接口*/public interface AccountDao {/*** 查询所有* @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);}
创建接口的实现类AccountDaoImpl.java
/*** 账户的持久层实现类*/public class AccountDaoImpl implements AccountDao {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 (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 (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);}}}
创建接口AccountService.java
/*** 账户的业务层接口*/public interface AccountService {/*** 查询所有* @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);}
创建接口的实现类AccountServiceImpl.java
/*** 账户的业务层实现类*/public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao 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);}}
编写测试类com.it.test,AccountServiceTest.java
/*** 使用Junit单元测试:测试我们的配置*/public class AccountServiceTest {@Testpublic void testFindAll() {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService as = (AccountService) ac.getBean("accountService");//3.执行方法List<Account> accounts = as.findAllAccount();for(Account account : accounts){System.out.println(account);}}@Testpublic void testFindOne() {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService as = (AccountService) ac.getBean("accountService");//3.执行方法Account account = as.findAccountById();System.out.println(account);}@Testpublic void testSave() {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService as = (AccountService) ac.getBean("accountService");Account account = new Account();account.setName("test");account.setMoney(12345f);//3.执行方法as.saveAccount(account);}@Testpublic void testUpdate() {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService as = (AccountService) ac.getBean("accountService");//3.执行方法Account account = as.findAccountById();account.setMoney(23456f);as.updateAccount(account);}@Testpublic void testDelete() {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService as = (AccountService) ac.getBean("accountService");//3.执行方法as.deleteAccount();}}
编写applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 配置Service --><bean id="accountService" class="com.it.service.impl.AccountServiceImpl"><!-- 注入dao --><property name="accountDao" ref="accountDao"></property></bean><!--配置Dao对象--><bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl"><!-- 注入QueryRunner --><property name="runner" ref="runner"></property></bean><!--配置QueryRunner,设置prototype为多例,表示每次调用都获取一个新的连接对象--><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/itcastspring"></property><property name="user" value="root"></property><property name="password" value="root"></property></bean></beans>
添加jdbc.properties文件
这里,也可以使用spring的${}动态赋值表达式,读取属性文件
第一步:添加jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/itcastspringjdbc.username=rootjdbc.password=root
第二步:修改applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="jdbc.properties"></context:property-placeholder><!-- 配置数据源 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!--连接数据库的必备信息--><property name="driverClass" value="${jdbc.driver}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></bean></beans>
使用import加载多个applicationContext.xml
让程序加载多个spring的配置文件,对spring的配置文件细分
applicationContext.xml:加载第三方的配置(数据源、QueryRunner)
applicationContext-dao.xml:加载自己创建的Dao对象
applicationContext-service.xml:加载自己创建的Service对象
applicationContext-redis.xml、applicationContext-mq.xml、applicationContext-mybatis.xml等

需要使用import加载
在applicationContext.xml中添加:
<!--加载其他spring的配置文件--><import resource="classpath:applicationContext-service.xml"></import><import resource="classpath:applicationContext-dao.xml"></import>
使用注解配置IOC
使用DBUtils对账号表实现CRUD
创建数据库
create table account(id int primary key auto_increment,name varchar(),money float)character set utf8 collate utf8_general_ci;insert into account(name,money) values('aaa',);insert into account(name,money) values('bbb',);insert into account(name,money) values('ccc',);
接口的实现类AccountDaoImpl.java修改
/*** 账户的持久层实现类*/@Repository("accountDao")public class AccountDaoImpl implements AccountDao {@Autowiredprivate 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);}}}
接口的实现类AccountServiceImpl.java修改
/*** 账户的业务层实现类*/@Service("accountService")public class AccountServiceImpl implements AccountService {@Autowiredprivate 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);}}
applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 告知spring在创建容器时要扫描的包 --><context:component-scan base-package="com.it"></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/itcastspring"></property><property name="user" value="root"></property><property name="password" value="root"></property></bean></beans>
企业开发的时候:一般配置文件(xml)+注解混合使用
配置文件:
- 第三方提供的对象(QueryRunner、C3P0),可以由配置文件XML完成
- 自己创建的对象(Controller、Service、Dao、工具类Utils),可以由注解进行完成
使用spring的注解配置,去掉applicationContext.xml中所有配置
准备:
- 导入Account.java
- 导入AccountDao.java和AccountDaoImpl.java
- 导入AccountService.java和AccountServiceImpl.java
- 导入AccountServiceTest.java的测试类
@Configuration注解
创建包config,创建SpringConfiguration.java类
@Configurationpublic class SpringConfiguration {}
表示该类是一个配置类,它的作用和applicationContext.xml是一样的
spring5中的新注解
@Configuration
作用:指定当前类是一个配置类,如同取代applicationContext.xml中的配置
细节:当配置类作为AnnotationConfigApplicationContext对象创建时,该注解可以不写。
@ComponentScan注解
@ComponentScan
作用:用于通过注解指定spring在创建容器时要扫描的包
属性:
value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包的范围。
我们使用此注解就等同于在xml中配置了:
<context:component-scan base-package="com.it"></context:component-scan
@Configuration@ComponentScan(value = {"com.it"})public class SpringConfiguration {}
@Bean注解
@Bean
作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
属性:
name:用于指定bean的id。当不写时,默认值是当前方法的名称
依赖注入细节:
我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象,如果有bean对象,将对象通过方法的形参注入到方法中使用。查找的方式和Autowired注解的作用是一样的
@Configuration//@ComponentScan(value = {"com.it"})public class SpringConfiguration {/*** 用于创建一个QueryRunner对象* @param dataSource* @return*/@Bean(name="runner")@Scope("prototype")public QueryRunner createQueryRunner(DataSource dataSource){return new QueryRunner(dataSource);}/*** 创建数据源对象* @return*/@Bean(name="ds")public DataSource createDataSource(){try {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass("com.mysql.jdbc.Driver");ds.setJdbcUrl("jdbc:mysql://localhost:3306/itcastspring");ds.setUser("root");ds.setPassword("root");return ds;}catch (Exception e){throw new RuntimeException(e);}}}

工厂AnnotationConfigApplicationContext.java
当配置类作为AnnotationConfigApplicationContext对象创建的参数时,@Configuration注解可以不写。
使用AccountServiceTest.java测试查询:
public class AccountServiceTest {@Testpublic void testFindAll() {ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);AccountService as = (AccountService)ac.getBean("accountService");//3.执行方法List<Account> accounts = as.findAllAccount();for(Account account : accounts){System.out.println(account);}}}
创建测试类QueryRunnerTest.java,测试QueryRunner是否是单例。
/*** 测试queryrunner是否单例*/public class QueryRunnerTest {@Testpublic void testQueryRunner(){//1.获取容易ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);//2.获取queryRunner对象QueryRunner runner = ac.getBean("runner",QueryRunner.class);QueryRunner runner1 = ac.getBean("runner",QueryRunner.class);System.out.println(runner == runner1);}}
@Import注解
@Import
作用:用于导入其他的配置类
属性:
value:用于指定其他配置类的字节码。
当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类
相当于applicationContext.xml中的">
第一步:创建配置类,JdbcConfig.java
将配置都放置到JdbcConfig中
public class JdbcConfig {/*** 用于创建一个QueryRunner对象* @param dataSource* @return*/@Bean(name="runner")@Scope("prototype")public QueryRunner createQueryRunner(DataSource dataSource){return new QueryRunner(dataSource);}/*** 创建数据源对象* @return*/@Bean(name="ds")public DataSource createDataSource(){try {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass("com.mysql.jdbc.Driver");ds.setJdbcUrl("jdbc:mysql://localhost:3306/itcastspring");ds.setUser("root");ds.setPassword("root");return ds;}catch (Exception e){throw new RuntimeException(e);}}}
用SpringConfiguration.java引入JdbcConfig的配置
//@Configuration@ComponentScan(value = {"com.it"})@Import(value= JdbcConfig.class)public class SpringConfiguration {}
@PropertySource注解
@PropertySource
作用:用于指定properties文件的位置
属性:
value:指定文件的名称和路径。
关键字:classpath,表示类路径下
在resource下创建 jdbcConfig.properties文件
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/itcastspringjdbc.username=rootjdbc.password=root
配置SpringConfiguration.java
//@Configuration@ComponentScan(value = {"com.it"})@Import(value= JdbcConfig.class)@PropertySource("classpath:jdbcConfig.properties")public class SpringConfiguration {}
配置JdbcConfig.java
*** 和spring连接数据库相关的配置类*/public class JdbcConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** 用于创建一个QueryRunner对象* @param dataSource* @return*/@Bean(name="runner")@Scope("prototype")public QueryRunner createQueryRunner(DataSource dataSource){return new QueryRunner(dataSource);}/*** 创建数据源对象* @return*/@Bean(name="ds")public DataSource createDataSource(){try {ComboPooledDataSource ds = new ComboPooledDataSource();// ds.setDriverClass("com.mysql.jdbc.Driver");// ds.setJdbcUrl("jdbc:mysql://localhost:3306/itcastspring");// ds.setUser("root");// ds.setPassword("root");ds.setDriverClass(driver);ds.setJdbcUrl(url);ds.setUser(username);ds.setPassword(password);return ds;}catch (Exception e){throw new RuntimeException(e);}}}
@Qualifier注解
作用:如果spring容器中出现了多个数据源类型,使用该注解指定注入的数据源。
修改JdbcConfig.java的配置。
/*** 用于创建一个QueryRunner对象* @param dataSource* @return*/@Bean(name="runner")@Scope("prototype")public QueryRunner createQueryRunner(@Qualifier(value = "ds2") DataSource dataSource){return new QueryRunner(dataSource);}/*** 创建数据源对象* @return*/@Bean(name="ds1")public DataSource createDataSource(){try {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass(driver);ds.setJdbcUrl("jdbc:mysql:///itcastspring");ds.setUser(username);ds.setPassword(password);return ds;}catch (Exception e){throw new RuntimeException(e);}}@Bean(name="ds2")public DataSource createDataSource2(){try {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass(driver);ds.setJdbcUrl("jdbc:mysql:///test");ds.setUser(username);ds.setPassword(password);return ds;}catch (Exception e){throw new RuntimeException(e);}}
为什么全注解开发呢?
因为springboot框架中的底层会体现,全注解的配置
使用spring整合Junit
什么是main方法?
main方法,应用程序的入口
2、什么是junit方法?
junit单元测试中,没有main方法也能执行
因为junit集成了一个main方法
该方法就会判断当前测试类中哪些方法有 @Test注解
junit就让有@Test注解的方法执行
3、junit方法测试spring的IOC和DI的问题?
junit不会管我们是否采用spring框架
在执行测试方法时,junit根本不知道我们是不是使用了spring框架
所以也就不会为我们读取配置文件(基于XML)、配置类(基于注解)、并创建spring核心容器
4、总结:
由以上三点可知
当测试方法执行时,没有Ioc容器,就算写了Autowired注解,也无法实现注入
但是如何通过junit加载Ioc容器(即srping容器)呢?
Spring整合junit
Spring整合junit的配置
导入spring整合junit的jar(坐标)
<dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
使用:@Runwith,加载SpringJUnit4ClassRunner.class
告知spring的运行器,spring和ioc创建是基于xml还是基于注解的,并且说明位置
使用@ContextConfiguration
locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
@ContextConfiguration(locations = **"classpath:applicationContext.xml"**)
classes:指定注解类所在地位置
@ContextConfiguration(classes = SpringConfiguration.**class**)
注意:当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上
/*** 使用Junit单元测试:测试我们的配置* Spring整合junit的配置* 1、导入spring整合junit的jar(坐标)* 2、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的* @Runwith* 3、告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置* @ContextConfiguration* locations:指定xml文件的位置,加上classpath关键字,表示在类路径下* classes:指定注解类所在地位置** 当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上*/@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = SpringConfiguration.class)public class AccountServiceTest {@Autowiredprivate AccountService as;@Testpublic void testFindAll() {//3.执行方法List<Account> accounts = as.findAllAccount();for(Account account : accounts){System.out.println(account);}}}
Spring_two的更多相关文章
随机推荐
- Opencv 张正友相机标定傻瓜教程
注: 程序所用的OpenCV版本是 2.4.10 ,3.0以上的版本可能会有不同 先贴一下完整的工程代码: #include "opencv2/core/core.hpp" #in ...
- twemproxy分片处理原理--剖析twemproxy代码正编
twemproxy在redis上能处理多命令流程只有mset,mget,del的命令,例如mset的话是mset k1 v1 k2 v2 k3 k3,mget的话是mget k1 k2 k3,del的 ...
- wpf 自定义窗口,最大化时覆盖任务栏解决方案
原文:wpf 自定义窗口,最大化时覆盖任务栏解决方案 相信很多人使用wpf时会选择自定义美观的窗口,因此会设置WindowStyle="None" 取消自带的标题栏.但这样使用 W ...
- kendo ui gird温馨提示(使用本地数据) 一个
加入js引用 <link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.common.min.css" r ...
- 关于hibernate组件配置
建立关系数据模型的一个重要原则是在不会导致数据冗余的前提下,尽可能减少数据库表的数目及表之间的外键参照关系.以员工信息为例,员工信息中有员工的家庭地址信息,如果把地址信息单独放在一张表中,然后建立员工 ...
- WPF学习笔记:(一)数据绑定与DataContext
前一段半心半意地学习了一下WPF,是从控件入手的,发现巨容易,甚至有些无趣.昨天面试,被问到了很多WPF的特性的东西,直接就傻了.于是乎,还是要去深刻的学习一下WPF.刚刚试了一下数据绑定,几次都没有 ...
- 特殊存储过程——触发器Trigger
触发器类型 insert 触发器delete 触发器update 触发器 Inserted和Deleted两个临时表的作用 Inserted:对于插入记录操作来说,插入表里存放的是要插入的数据:对于更 ...
- C#(WPF)为Grid添加实线边框。
原文:C#(WPF)为Grid添加实线边框. 相信大家在做WPF项目的时候,都会用到Grid这个布局控件,一般情况下,如果只是为了布局,那就不需要显示它的边框,但是也有特殊需求,如果把它当做表格来使用 ...
- WPF 4 开发Windows 7 跳转列表(JumpList)
原文:WPF 4 开发Windows 7 跳转列表(JumpList) 在之前写过的<Windows 7 任务栏开发系列>中我们通过Visual Studio 2008 借助微软 ...
- StaticResource和DynamicResource
Resource 资源(Resource)是保存在可执行文件中的一种不可执行数据,用来保存一些可以被重复利用的样式,对象定义以及一些传统的资源如二进制数据,图片等等我们可以在任何元素上定义资源 Sta ...