前面两篇文章和大家分享了spring的IOC和DI工作原理。今天我们利用spring+dbutils+mysql来做一个简单的demo。这个demo的功能主要是银行账户的一些信息,实现基本的增删查改操作。
- 采用XML形式实现demo
- 采用XML和注解形式实现demo
- 采用注解形式实现demo
首先,我们创建一个maven工程,搭建spring的开发环境。
项目结构如下:
读者暂且不用管config包面的东西了。这个就是我们正常的三层架构模式。
pom文件如下:
<?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.tff.demo</groupId>
<artifactId>spring_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<!-- spring 开发环境 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!-- dbutils数据操作工具类 -->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.4</version>
</dependency>
<!-- mysql数据库驱动类 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<!-- junit测试单元 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!-- c3p0数据库连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
</project>
数据库文件
//创建表文件
create table account1(
id int PRIMARY key auto_increment,
name varchar(40) COMMENT '账户名',
money float COMMENT '账户余额'
);
//插入数据
insert into account1(name,money) values('张三',4545);
insert into account1(name,money) values('zyy',4545);
insert into account1(name,money) values('gxr',454545);
insert into account1(name,money) values('lyc',78787);
insert into account1(name,money) values('zyt',78787);
insert into account1(name,money) values('tff',99999999999.999);
insert into account1(name,money) values('weilai',8888888888.888);
实体类:
package com.tff.demo.entity;
import com.sun.org.apache.xml.internal.serialize.Serializer;
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 +
'}';
}
}
基于XML形式来实现demo
dao层
package com.tff.demo.dao;
import com.tff.demo.entity.Account;
import java.util.List;
public interface AccountDao {
//查询所有的账户信息
List<Account> getAccountAll();
//按照条件来查询
Account getAccount(Integer id);
//增加一个账户信息
int saveAccount(Account account);
//修改账户信息
int updateAccount(Account account);
//删除账户信息
int deleteAccount(Integer id);
}
package com.tff.demo.dao.impl;
import com.tff.demo.dao.AccountDao;
import com.tff.demo.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.util.List;
public class AccountImpl implements AccountDao {
//这个是dbutils工具类中的属性,用来完成对数据的增删改查
private QueryRunner runner;
//因为我们使用set方式注入数据,所以提供必要的set方法和默认构造函数
public void setRunner(QueryRunner runner) {
this.runner = runner;
}
//查询所有的用户账户信息
public List<Account> getAccountAll() {
try{
return runner.query("select * from account1",new BeanListHandler<Account>(Account.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
//按照id来查询个人的账户信息
public Account getAccount(Integer id) {
try{
return runner.query("select * from account1 where id = ?",new BeanHandler<Account>(Account.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
//注册一个账户信息
public int saveAccount(Account account) {
try{
return runner.update("insert into account1(name,money)values(?,?)",account.getName(),account.getMoney());
}catch (Exception e){
throw new RuntimeException(e);
}
}
//修改一个账户信息
public int updateAccount(Account account) {
try{
return runner.update("update account1 set name = ?,money = ? where id = ?",account.getName(),account.getMoney(),account.getId());
}catch (Exception e){
throw new RuntimeException(e);
}
}
//删除一个账户信息
public int deleteAccount(Integer id) {
try{
return runner.update("delete from account1 where id = ?",id);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
service层
package com.tff.demo.service;
import com.tff.demo.entity.Account;
import java.util.List;
public interface AccountService {
//查询所有的账户信息
List<Account> getAccountAll();
//按照条件来查询
Account getAccount(Integer id);
//增加一个账户信息
int saveAccount(Account account);
//修改账户信息
int updateAccount(Account account);
//删除账户信息
int deleteAccount(Integer id);
}
package com.tff.demo.service.impl;
import com.tff.demo.dao.AccountDao;
import com.tff.demo.entity.Account;
import com.tff.demo.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
public class AccountServiceImpl implements AccountService {
//dao层属性,用来访问dao层的方法
private AccountDao accountDao;
//使用set方式注入,提供标准的set方法和默认构造函数
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
//一下都是调用dao层的方法,实现对数据库的访问。对于初学者,可能觉得这一层没有必要,是的,因为我们现在还没有实现业务逻辑的控制,就只是简单的调用dao层方法而已。
public List<Account> getAccountAll() {
return accountDao.getAccountAll();
}
public Account getAccount(Integer id) {
return accountDao.getAccount(id);
}
public int saveAccount(Account account) {
return accountDao.saveAccount(account);
}
public int updateAccount(Account account) {
return accountDao.updateAccount(account);
}
public int deleteAccount(Integer id) {
return accountDao.deleteAccount(id);
}
}
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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx">
<!-- 配置service层 -->
<bean id="accountService" class="com.tff.demo.service.impl.AccountServiceImpl">
<!-- 注入数据 -->
<property name="accountDao" ref="dao"></property>
</bean>
<!-- 配置dao层-->
<bean id="dao" class="com.tff.demo.dao.impl.AccountImpl">
<!-- 注入数据 -->
<property name="runner" ref="queryRunner"></property>
</bean>
<context:component-scan base-package="com.tff.demo"></context:component-scan>
<!-- 配置queryRunner,它提供了一个有参构造器来进行注入 -->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<!-- 注入数据源 -->
<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://10.10.6.45:3396/TEST"></property>
<property name="user" value="root"></property>
<property name="password" value="Az.123456"></property>
</bean>
</beans>
简单说明一下:
我们先注入的是service层的数据,在service层我们引用了dao层的属性,所以,要使用ref标签来进行注入。那ref标签注入的bean类型必须是要在springIOC容器中出现过的对象。所以,我们还要配置dao层,这样,dao层这个bean类型就存在于springIOC容器中了。我们又发现,在dao层我们要使用dbutils工具实现对数据库的访问,我们也要对他进行类似上面的操作。同理,数据源也是一样。
大家对dbutils和C3P0数据库连接池不了解的没关系,我们这次的重点不在这里。有兴趣的可以自己去查阅资料。
接下来我们看一下测试类:
import com.tff.demo.config.SpringConfiguration;
import com.tff.demo.entity.Account;
import com.tff.demo.service.AccountService;
import org.apache.commons.dbutils.QueryRunner;
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;
//利用Junit测试单元进行测试
public class AccountServiceTest {
@Test
public void testFindAll(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = ac.getBean("accountService",AccountService.class);
List<Account> list = accountService.getAccountAll();
for (Account acc: list) {
System.out.println(acc.toString());
}
}
@Test
public void testDelete(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = ac.getBean("accountService",AccountService.class);
int k = accountService.deleteAccount(2);
System.out.println(k);
}
@Test
public void updateAccount(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = ac.getBean("accountService",AccountService.class);
Account account = new Account();
account.setId(2);
account.setName("zyy2");
account.setMoney(454545454545.789F);
int up = accountService.updateAccount(account);
System.out.println(up);
}
@Test
public void insertAccount(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = ac.getBean("accountService",AccountService.class);
Account account = new Account();
account.setName("dt");
account.setMoney(454545545.789F);
accountService.saveAccount(account);
}
}
运行结果:
如果大家在看的过程中,对spring的IOC和注入方式又不理解的,建议大家先看上两篇文章。里面详细解说了spring的IOC机制和DI机制。
基于XML和注解形式来实现demo
dao层
package com.tff.demo.dao;
import com.tff.demo.entity.Account;
import java.util.List;
public interface AccountDao {
//查询所有的账户信息
List<Account> getAccountAll();
//按照条件来查询
Account getAccount(Integer id);
//增加一个账户信息
int saveAccount(Account account);
//修改账户信息
int updateAccount(Account account);
//删除账户信息
int deleteAccount(Integer id);
}
package com.tff.demo.dao.impl;
import com.tff.demo.dao.AccountDao;
import com.tff.demo.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.util.List;
//这个注解已经讲过了
@Repository
public class AccountImpl implements AccountDao {
//自动化装配
@Autowired
private QueryRunner runner;
public List<Account> getAccountAll() {
try{
return runner.query("select * from account1",new BeanListHandler<Account>(Account.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
public Account getAccount(Integer id) {
try{
return runner.query("select * from account1 where id = ?",new BeanHandler<Account>(Account.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
public int saveAccount(Account account) {
try{
return runner.update("insert into account1(name,money)values(?,?)",account.getName(),account.getMoney());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public int updateAccount(Account account) {
try{
return runner.update("update account1 set name = ?,money = ? where id = ?",account.getName(),account.getMoney(),account.getId());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public int deleteAccount(Integer id) {
try{
return runner.update("delete from account1 where id = ?",id);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
service层
package com.tff.demo.service;
import com.tff.demo.entity.Account;
import java.util.List;
public interface AccountService {
//查询所有的账户信息
List<Account> getAccountAll();
//按照条件来查询
Account getAccount(Integer id);
//增加一个账户信息
int saveAccount(Account account);
//修改账户信息
int updateAccount(Account account);
//删除账户信息
int deleteAccount(Integer id);
}
package com.tff.demo.service.impl;
import com.tff.demo.dao.AccountDao;
import com.tff.demo.entity.Account;
import com.tff.demo.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AccountServiceImpl implements AccountService {
//按照类型自动装配
@Autowired
//@Resource(name = "id的属性值") 这个注解也是可以的
private AccountDao accountDao;
public List<Account> getAccountAll() {
return accountDao.getAccountAll();
}
public Account getAccount(Integer id) {
return accountDao.getAccount(id);
}
public int saveAccount(Account account) {
return accountDao.saveAccount(account);
}
public int updateAccount(Account account) {
return accountDao.updateAccount(account);
}
public int deleteAccount(Integer id) {
return accountDao.deleteAccount(id);
}
}
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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx">
<!-- 告诉spring去那些包下面扫描要交给spring实例化的对象 -->
<context:component-scan base-package="com.tff.demo"></context:component-scan>
<!-- 配置queryRunner,它提供了一个有参构造器来进行注入 -->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<!-- 注入数据源 -->
<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://10.10.6.45:3396/TEST"></property>
<property name="user" value="root"></property>
<property name="password" value="Az.123456"></property>
</bean>
</beans>
测试类:
import com.tff.demo.config.SpringConfiguration;
import com.tff.demo.entity.Account;
import com.tff.demo.service.AccountService;
import org.apache.commons.dbutils.QueryRunner;
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 AccountServiceTest {
@Test
public void testFindAll(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//这里需要注意一下,为什么这里是accountServiceImpl而不是上一次的accountService,因为我们在Service层的实现类的Service注解后面省略了value属性,所以,默认就是当前类名(类名首字母小写),如果需要指定,可以这样Server(value="名字")
AccountService accountService = ac.getBean("accountServiceImpl",AccountService.class);
List<Account> list = accountService.getAccountAll();
for (Account acc: list) {
System.out.println(acc.toString());
}
}
@Test
public void testDelete(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = ac.getBean("accountServiceImpl",AccountService.class);
int k = accountService.deleteAccount(2);
System.out.println(k);
}
@Test
public void updateAccount(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = ac.getBean("accountServiceImpl",AccountService.class);
Account account = new Account();
account.setId(2);
account.setName("zyy2");
account.setMoney(454545454545.789F);
int up = accountService.updateAccount(account);
System.out.println(up);
}
@Test
public void insertAccount(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = ac.getBean("accountServiceImpl",AccountService.class);
Account account = new Account();
account.setName("dt");
account.setMoney(454545545.789F);
accountService.saveAccount(account);
}
}
测试结果:
小结一下:跟完全XML形式配置哪里不一样呢?好像也差不多。就是spring的配置文件中我们要告诉spring去哪个包下面扫面要交给spring容器帮我们实例化的bean 对象。
基于全注解形式来实现demo
dao层
package com.tff.demo.dao;
import com.tff.demo.entity.Account;
import java.util.List;
public interface AccountDao {
//查询所有的账户信息
List<Account> getAccountAll();
//按照条件来查询
Account getAccount(Integer id);
//增加一个账户信息
int saveAccount(Account account);
//修改账户信息
int updateAccount(Account account);
//删除账户信息
int deleteAccount(Integer id);
}
package com.tff.demo.dao.impl;
import com.tff.demo.dao.AccountDao;
import com.tff.demo.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.util.List;
@Repository
public class AccountImpl implements AccountDao {
@Autowired
private QueryRunner runner;
public List<Account> getAccountAll() {
try{
return runner.query("select * from account1",new BeanListHandler<Account>(Account.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
public Account getAccount(Integer id) {
try{
return runner.query("select * from account1 where id = ?",new BeanHandler<Account>(Account.class));
}catch (Exception e){
throw new RuntimeException(e);
}
}
public int saveAccount(Account account) {
try{
return runner.update("insert into account1(name,money)values(?,?)",account.getName(),account.getMoney());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public int updateAccount(Account account) {
try{
return runner.update("update account1 set name = ?,money = ? where id = ?",account.getName(),account.getMoney(),account.getId());
}catch (Exception e){
throw new RuntimeException(e);
}
}
public int deleteAccount(Integer id) {
try{
return runner.update("delete from account1 where id = ?",id);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
service层
package com.tff.demo.service;
import com.tff.demo.entity.Account;
import java.util.List;
public interface AccountService {
//查询所有的账户信息
List<Account> getAccountAll();
//按照条件来查询
Account getAccount(Integer id);
//增加一个账户信息
int saveAccount(Account account);
//修改账户信息
int updateAccount(Account account);
//删除账户信息
int deleteAccount(Integer id);
}
package com.tff.demo.service.impl;
import com.tff.demo.dao.AccountDao;
import com.tff.demo.entity.Account;
import com.tff.demo.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
public List<Account> getAccountAll() {
return accountDao.getAccountAll();
}
public Account getAccount(Integer id) {
return accountDao.getAccount(id);
}
public int saveAccount(Account account) {
return accountDao.saveAccount(account);
}
public int updateAccount(Account account) {
return accountDao.updateAccount(account);
}
public int deleteAccount(Integer id) {
return accountDao.deleteAccount(id);
}
}
到这里,我们发现是不是跟基于注解和XML来实现的demo的方式一样,是的,至少在dao层和service层是一样的,还记得第三种的实现方式叫“全注解实现”,什嘛意思,就是这次肯定不会再有XML文件出现了,当然,程序运行的时候不会再去加载spring的配置文件。(哦买噶,XML是不是已经悄悄的留下了伤心的泪水,太伤人家的心了。)
怎么会,出来混迟早是要还的。只不过是换了一种存在方式而已(哈哈哈哈哈……)。他就是我们前面说的config包下面的东东,一起来看一下:
目录结构就是这样的(包名和类名自己随便起,只要符合java的命名规则就OK)
SpringConfiguration配置类代码
package com.tff.demo.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import javax.sql.DataSource;
@Configuration
@ComponentScan(basePackages = {"com.tff.demo"})
public class SpringConfiguration {
//把当前方法的返回值作为bean的对象存入spring的IOC容器中,如果省略name值,他的id为方法名
@Bean(name = "runner")
@Scope("prototype") //bean 对象的作用范围
public QueryRunner getNewQueryRunner(DataSource dataSource){
return new QueryRunner(dataSource);
}
@Bean(name = "dataSource")
public DataSource getDataSource(){
ComboPooledDataSource cs = new ComboPooledDataSource();
try{
cs.setDriverClass("com.mysql.jdbc.Driver");
cs.setJdbcUrl("jdbc:mysql://10.10.6.45:3396/TEST");
cs.setUser("root");
cs.setPassword("Az.123456");
return cs;
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
稍后我们来看那些不认识的注解
测试类:
import com.tff.demo.config.SpringConfiguration;
import com.tff.demo.entity.Account;
import com.tff.demo.service.AccountService;
import org.apache.commons.dbutils.QueryRunner;
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 AccountServiceTest {
@Test
public void testFindAll(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
AccountService accountService = ac.getBean("accountServiceImpl",AccountService.class);
List<Account> list = accountService.getAccountAll();
for (Account acc: list) {
System.out.println(acc.toString());
}
}
@Test
public void testDelete(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
AccountService accountService = ac.getBean("accountServiceImpl",AccountService.class);
int k = accountService.deleteAccount(2);
System.out.println(k);
}
@Test
public void updateAccount(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
AccountService accountService = ac.getBean("accountServiceImpl",AccountService.class);
Account account = new Account();
account.setId(2);
account.setName("zyy2");
account.setMoney(454545454545.789F);
int up = accountService.updateAccount(account);
System.out.println(up);
}
@Test
public void insertAccount(){
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
AccountService accountService = ac.getBean("accountService",AccountService.class);
Account account = new Account();
account.setName("dt");
account.setMoney(454545545.789F);
accountService.saveAccount(account);
}
}
运行结果:
另外,需要大家注意的是,在测试类中我们不在是加载类路径下面的spring配置文件,而是使用注解的方式类实现:
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
希望大家仔细恳看清这一点。
配置类的作用:
其实就和bean.xml是一样的
现在我来解释一下配置类的一些注解,也是spring中一些新的注解:
Configuration:
作用:指定当前类是一个配置类
ComponentScan:
作用:用于通过注解指定spring在创建容器时要扫描的包
属性:他有两个属性,分别是value和basePackages,作用是一样的。都是用于指定创建容器时要扫描的包。等同于XML中配置:
<context:component-scan base-package=“com.tff.demo”></context:component-scan>
Bean:
作用:用于把当前方法的返回值作为bean对象存入spring的IOC容器中。
属性:
name:用于指定bean的id,当不写时,默认值是当前方法的名称,而不是当前类的名称。
备注:有一个问题,不知道大家有没有发现,就是我们去掉配置类上面的@Configuration注解,也能正常运行处结果。这是为什么?
说明一下:就是如果这个配置类只是作为注解构造函数里面的一个参数时,我们可以不写Configuration这个注解。如果,我们需要配置的东西,需要用到ComponentScan去扫描的时候,这个时候还不写Configuration注解的时候,他不会去扫描的。因为他不是一个配置类。
demo中刚好作为一个参数传入,所以不写也是可以的。如果有多个配置类,不想写Configuration注解,就把他作为参数穿进去就可以了。
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
加粗部分就是作为这个类的一个参数传递进去,如果有多个,写在后面,逗号隔开。
所以,@Configuration这个注解什么时候能去掉,什么时候不能去掉,希望大家也搞清楚。
这个demo就跟大家分享完了。也不知道会不会理解了。还是来总结一下:
总结:
spring的配置方式和spring的注入方式是两个概念。请不要混淆这两个概念。配置方式更多的是spring帮我们实例化bean 对象。而注入方式更多的是给bean对象的成员属性赋值的。
spring的配置方式就目前而言只有XML和注解方式
spring的注入方式有基于构造函数、set方法和注解三种方式。
今天人生中第23个感恩节,虽然是一个西方的节日,不是我们中国的传统节日。但是,我们仍然要心怀感恩。感恩曾经给过你帮助的人,感恩那些伤害过你的人。感恩父母,感恩祖国。感恩这世间的一花一草。正式因为有他们的存在,我们的世界才变得精彩、变得美好。