Java框架-Spring概念及纯xml配置
1. 三层架构中的spring及spring概述
1.1 三层架构中的spring
- Spring框架对三层架构都有支持,dao提供支持(如JDBCTemplate)、service提供事务支持、web提供了springmvc框架支持等。
1.2 Spring的概述
- Spring是于2003年兴起的一个轻量级的Java开发开源框架。
- 由Rod Johnson首次提出。
- Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。
1.3 Spring优势
- 方便解耦,简化开发
- AOP编程的支持
- 声明式事务的支持
- 方便程序的测试
- 方便继承各种优秀的框架
- 降低JavaEE API的使用难度等
1.4 Spring体系结构
七大模块
- Spring Core:核心容器,Spring的基本功能
- Spring AOP:面向切面编程
- Spring ORM:提供多个第三方持久层框架的整合
- Spring DAO:简化DAO开发
- Spring Context:配置文件,为Spring提供上下文信息,提供了框架式的对象访问方法
- Spring Web:提供针对Web开发的集成特性
- Spring MVC:提供了Web应用的MVC实现
2. 程序中的耦合与解耦
-
耦合:程序中的依赖关系。其中一种依赖关系是对象之间的关联性。对象之间关联性越高,维护成本越高。
-
划分模块的一个准则就是高内聚低耦合
-
高内聚,低耦合:类内部的关系越紧密越好,类与类之间的关系越少越好。
2.1 解决数据库驱动注册代码与连接数据库代码的耦合问题
- 使用反射注册驱动,用于解决两者依赖关系;
- 将驱动全限定类字符串写入配置文件中,注册驱动时加载配置文件,用于使用反射创建对象时驱动类字符串在代码中写死的问题
2.2 解决三层架构之间的耦合问题
表现层需要创建业务层的实例来调用业务层的方法,同样业务层也要创建持久层的示例来调用持久层的方法。按照传统开发方法,创建实例都是直接new,一旦更换数据库或者拓展已有业务(新的业务层接口实例),就会影响到原有的代码,需要修改源代码(也就是耦合问题)
解决耦合问题的关键,业务层或持久层的实例不手动直接创建,而是交由第三方(工厂)创建。通过修改工厂的配置文件获取对应的实例,不需要修改原有代码,实现解耦
下面简单举例
2.2.1 举例准备工作
-
dao接口
public interface IAccountDao { void save(); }
-
dao实现类
//mysql
public class AccountDaoImpl implements IAccountDao {
@Override
public void save() {
System.out.println("mysql保存用户");
}
}
//oracle
public class AccountDaoOracleImpl implements IAccountDao {
@Override
public void save() {
System.out.println("oracle保存用户");
}
}
-
service接口
public interface IAccountService { void save(); }
-
service实现类
public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao = new AccountDaoImpl(); @Override public void save() { accountDao.save(); } }
2.2.2 使用工厂解耦
2.2.2.1 配置文件
#dao层
#mysql
AccountDao=com.azure.dao.impl.AccountDaoImpl
#oracle
#AccountDao=com.azure.dao.impl.AccountDaoOracleImpl
#service层
AccountService=com.azure.service.impl.AccountServiceImpl
2.2.2.2 工厂类
public class BeanFactory {
/*
读取properties配置文件有两种方式:
1、直接创建properties对象,使用关联配置文件的输入流加载文件数据到properties中;
2、通过ResourceBundle加载配置文件
1)只可以加载properties后缀的配置文件
2)只能加载类路径下的properties配置文件
*/
//读取配置文件并创建对应的对象
//使用泛型,通过传入泛型类型返回对应类型的对象
public static <T> T getBean(String name,Class<T> clazz) {
try {
//读取配置文件数据
ResourceBundle bundle = ResourceBundle.getBundle("instance");
//获取key对应的value。比如AccountDao=com.azure.dao.impl.AccountDaoImpl
String value = bundle.getString(name);
return (T) Class.forName(value).getConstructor().newInstance();//jdk1.9做法
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
2.2.2.3 service层解耦
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao = BeanFactory.getBean("AccountDao", IAccountDao.class);
@Override
public void save() {
accountDao.save();
}
}
2.2.2.4 表现层解耦
- 这里就在测试类中模拟
public class app {
public static void main(String[] args) {
//使用工厂创建service对象
IAccountService accountService = BeanFactory.getBean("AccountService", IAccountService.class);
accountService.save();
}
}
2.2.2.5 小结
通过修改配置文件即可完成dao或service的转换,不需要修改已有代码
3. IOC
使用工厂类实现三层架构的解耦,其核心思想就是
- 通过读取配置文件使用反射技术创建对象;
- 将创建的对象存储。使用时直接取出存储的对象。
其核心思想归纳起来就是IOC(Inversion Of Control 控制反转)
3.1 IOC概念
- 把创建对象的权利交给框架
- 包含依赖注入(Dependency Injection)和依赖查找(Dependency Lookup)
4. Spring IOC容器
- 简而言之,IOC容器是用来创建对象,并给对象属性赋值
下面将创建一个简单的IOC案例
4.1 创建简单案例
4.1.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.azure</groupId>
<artifactId>day51projects_spring_IOC</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--引入spring-context包,包含了spring的核心ioc容器所需要的最小包。-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--引入junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
4.1.2 创建实体类
public class User implements Serializable {
public User(){
//使用无参实例化User对象时都会进入
System.out.println("创建User对象");
}
}
4.1.3 ioc容器配置文件
- 使用快捷方式创建,会自动引入约束
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--Spring的IOC容器通过配置bean标签表示要创建的对象-->
<bean id="user" class="com.azure.entity.User"></bean>
</beans>
4.1.4 测试类
public class Test01 {
@Test
public void test(){
//创建ioc容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//从容器中获取对象
User user = (User) ac.getBean("user");
System.out.println(user);
}
}
4.2 创建IOC容器的几种方式
1.FileSystemXmlApplicationContext:加载本地的配置文件
2.ClassPathXmlApplicationContext:加载类路径下的配置文件(重点)
3.AnnotationConfigWebApplicationContext:注解方式开发创建容器
4.WebApplicationContext:web项目中创建容器
5.BeanFactory:使用工厂创建对象
疑问:BeanFactory与ApplicationContext创建容器区别?
-
BeanFactory 在创建容器时候,没有自动创建对象
-
ApplicationContext 在创建容器时候,默认自动创建对象。
public class Test02 {
/*1.FileSystemXmlApplicationContext:加载本地的配置文件*/
@Test
public void test_file(){
//获得配置文件的真实路径
String path = "E:\\Java_study\\JavaprojectsIV\\day51projects_spring_IOC\\src\\main\\resources\\bean.xml";
//从容器中获取对象
ApplicationContext ac = new FileSystemXmlApplicationContext(path);
User user = (User) ac.getBean("user");
System.out.println(user);
}
/*2.ClassPathXmlApplicationContext:加载类路径下的配置文件(重点)*/
@Test
public void test_class(){
//类路径下要有bean.xml
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//从容器中获取对象
User user = (User) ac.getBean("user");
System.out.println(user);
}
/*3.AnnotationConfigWebApplicationContext:注解方式开发创建容器*/
@Test
public void test_annotation(){
/*//程序中要有SpringConfig类,表示容器类(相当于bean.xml)
ApplicationContext ac = new AnnotationConfigApplicationContext("SpringConfig.class");
//从容器中获取对象
User user = (User) ac.getBean("user");
System.out.println(user);*/
}
/*4.使用BeanFactory顶级接口创建容器*/
@Test
public void test_factory(){
Resource resource = new ClassPathResource("bean.xml");
BeanFactory factory = new XmlBeanFactory(resource);
User user = (User) factory.getBean("user");//创建User对象
}
}
4.3 创建容器(bean标签)的具体配置
-
常用配置
id、class,可选scope、lazy-init、init-method、destroy-method
<!--
创建对象的细节
bean 标签: 用来创建对象
其属性值包括:
- id (常用)指定对象的名称,一次指定一个引用名称。单例模式下所获取对象只有一个
- name 指定对象的名称,一次可以指定多个名称,多个名称之间用逗号或者空格隔开。单例模式下多个名称所获取的对象均为同一个
- class 指定对象的全路径
- scope 表示对象范围,可选值有:
singleton 单例 (默认值,创建容器时候就创建对象)
prototype 多例(始终都是在使用的时候创建新的对象)
request (少用)对象范围与request域一致,只在web项目有此选项
session (少用)对象范围与session域一致,只在web项目有此选项
global session (少用)在分布式系统使用,如果不是分布式系统相当于session,只在web项目有此选项
- lazy-init="true" 延迟初始化,表示单例的对象在第一次使用时候才创建。该属性对多例模式无效果。
- init-method="init" 创建对象之后执行
- destroy-method="preDestroy" 容器销毁之前执行。只对单例有效,单例下只创建一个对象,每次获取都是同一个,ioc容器会保存该对象,所以可以调用该对象的preDestory方法。
但多例模式无效,因为每次创建都是不同的对象,ioc容器不会保存对象,所以无法调用对象的preDestory方法
-->
<bean
id="user"
name="user2,user3"
class="com.azure.entity.User"
scope="prototype"
lazy-init="true"
init-method="init" destroy-method="preDestory"></bean>
-
注意事项:
id和name的作用相同,均是指定对象的名称,用于通过该名称获取ioc容器中的对象。但是形式不同。id不能指定多个名称,name可以指定多个名称。按照实际开发,更常用的是id。
4.4 创建对象的方式(控制反转)
4.4.1 调用无参构造函数创建对象
- 使用无参数构造函数创建对象(有参数构造函数在依赖注入中讲述)
-
创建实体类
-
在bean.xml中配置对应的bean标签
4.4.2 使用工厂类的实例方法
-
创建工厂类
public class UserFactory { /*1.通过实例方法返回对象*/ public User createUser(){ System.out.println("工厂实例方法创建一个对象"); return new User(); } }
-
配置bean.xml
- 运用到的bean标签属性:
- factory-bean:用于指定引用容器中的工厂对象;
- factory-method:用于指定工厂对象的实例方法。
<!--1.使用工厂实例方法创建对象--> <!--1.1 创建工厂类--> <bean id="factory" class="com.azure.factory.UserFactory"></bean> <!--1.2 调用工厂实例方法--> <!--factory-bean用于指定引用容器中的工厂对象--> <!--factory-method用于指定工厂对象的实例方法--> <bean id="user" factory-bean="factory" factory-method="createUser"></bean>
- 运用到的bean标签属性:
4.4.3 使用工厂类的静态方法
-
工厂类中添加静态方法
*2.通过静态方法返回对象*/ public static User createUser_static(){ System.out.println("工厂静态方法创建一个对象"); return new User(); }
-
配置bean.xml
<!--2.使用工厂静态方法创建对象--> <!--class与factory-method在同一个bean标签中使用,不会创建class对象。--> <bean id="user1" class="com.azure.factory.UserFactory" factory-method="createUser_static"/>
4.5 给对象属性赋值(DI依赖注入)
4.5.1调用有参构造函数创建对象
-
创建实体类对象
public class Student { private int id; private String name; //使用有参构造函数创建对象,实体类必须有有参构造函数 public Student(int id, String name) { this.id = id; this.name = name; } /*省略toString、getter&setter*/ }
-
配置bean.xml
-
常用index、value和ref三个属性
<!--使用有参构造函数创建对象--> <!-- 有参构造函数: constructor-arg 通过构造函数给对象属性赋值 - index 表示第几个参数,从0开始 - value 参数值 - name 对应构造函数形参名称 如构造函数public User(int id,String name)中的参数id或者name - type 表示构造函数参数的类型;如果是引用对象写类型全名 - ref 参数的值是引用容器中的另外一个对象(重点) --> <bean id="student" class="com.azure.entity.Student"> <constructor-arg index="0" value="10"></constructor-arg> <constructor-arg index="1" ref="str"></constructor-arg> </bean> <!--创建字符串并存入ioc容器中--> <bean id="str" class="java.lang.String"> <constructor-arg index="0" value="明明"></constructor-arg> </bean>
4.5.2 使用set方法注入依赖
-
创建实体类对象,并提供set方法给对象属性赋值
- 注意:实体类对象必须有无参构造函数
-
配置bean.xml
<!--使用set方法注入依赖--> <!-- 1.在bean标签体中使用property标签赋值 配置property标签,相当于调用set方法给对象属性赋值。 <property name="id" 相当于调用public void setId(int id); 2.总结: 1)property标签是给对象的属性赋值 2)property标签的name属性值不能乱写,必须是对象属性名 对象属性名:get或者set方法后面的部分且首字母小写。 举例:void setId(..) 中的id就是属性 --> <bean id="student2" class="com.azure.entity.Student"> <property name="id" value="12"></property> <property name="name" ref="str"></property> </bean>
4.5.3 使用p名称空间注入依赖
-
也是调用set方法给对象属性赋值
-
在spring3.0之后版本才有的,主要目的是为了简化配置
-
配置bean.xml,配置时要在beans标签中引入
xmlns:p="http://www.springframework.org/schema/p"
<!--使用p名称空间赋值-->
<!--p:id 相当于调用setId()方法
p:name-ref 相当于调用setName()方法,传入的值引用的是容器中的对象
-->
<bean id="student3" class="com.azure.entity.Student" p:id="168" p:name-ref="str"></bean>
4.6 给集合属性赋值
-
实体类,要有set/get方法
-
配置bean.xml
<!--给集合属性赋值--> <bean id="students" class="com.azure.entity.Student"> <!--给list集合赋值--> <property name="list"> <list> <value>cn</value> <value>usa</value> </list> </property> <!--给set集合赋值--> <property name="set"> <set> <value>cn</value> <value>usa</value> </set> </property> <!--给map集合赋值--> <property name="map"> <map> <entry key="cn" value="China"/> <entry key="usa" value="America"/> </map> </property> <!--给properties集合赋值--> <property name="properties"> <props> <prop key="cn">China</prop> <prop key="usa">America</prop> </props> </property> </bean>
5. 使用纯xml改造三层架构案例
-
添加依赖(pom.xml)
<dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies>
-
service的实例
public class AccountServiceImpl implements IAccountService { /*由spring的ioc容器注入dao*/ private IAccountDao accountDao;//先定义dao对象 //注入方法(对应bean.xml中的property标签) //使用set方法给dao对象赋值!!方法的参数就是ioc容器中保存的dao对象 public void setAccountDao(IAccountDao accountDao) { this.accountDao=accountDao; } @Override public void save() { accountDao.save(); } }
-
配置bean.xml
<!--创建dao对象,注意,这里的class属性值是dao的实现类--> <bean id="accountDao" class="com.azure.dao.impl.AccountDaoImpl"></bean> <!--创建service,注入dao,注意,这里的class属性值是service的实现类--> <bean id="accountService" class="com.azure.service.impl.AccountServiceImpl"> <!--注入dao,这里的property相当于set方法--> <property name="accountDao" ref="accountDao"></property> </bean>
-
测试类
public class app { public static void main(String[] args) { //创建容器 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //使用工厂创建service对象 IAccountService accountService = ac.getBean("accountService", IAccountService.class); accountService.save(); } }
5.1 小结
-
该改造方法的思路是
- 在ioc容器中创建dao对象,对应bean.xml中的第一个bean标签;
- 在ioc容器中创建service对象,而service对象中包含dao对象(需要使用dao对象调用dao层方法),所以需要将ioc的dao对象赋值给service里面的dao对象。本例中是使用set方法将ioc的dao对象注入,所以使用到property标签;
- 因为使用set方法注入dao,所以在service类中需要提供dao对象的set方法
-
所谓的注入依赖,就是给对象属性赋值
6. 使用spring的IOC实现CRUD(基于xml)
- 需求:根据三层架构,使用基于xml的spring实现CRUD
6.1 准备工作
- 准备account表,并使主键自增。表格包括字段accountId(主键)、uid、money
6.2 环境搭建
6.2.1pom.xml配置
<?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.azure</groupId>
<artifactId>day52projects_spring_xml</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--导入spring组件包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--导入druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--导入mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!--导入junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
6.3 实体类
public class account {
private int accountId;
private int uid;
private double money;
/*省略无参、有参、toString、getter&setter*/
}
6.4 dao代码
6.4.1 dao接口代码
public interface IAccountDao {
//添加
void save(Account account);
//更新
void update(Account account);
//删除
void delete(int aid);
//查询
List<Account> findAll();
}
6.4.2 dao实现类
public class AccountDaoImpl implements IAccountDao {
private JdbcTemplate jdbcTemplate;
/*使用SpringIOC容器注入jdbcTemplate对象,提供set方法*/
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void save(Account account) {
jdbcTemplate.update("insert into account values (null,?,?)",account.getUid(),account.getMoney());
}
@Override
public void update(Account account) {
jdbcTemplate.update("update account set uid=?,money=? where accountId=?",account.getUid(),account.getMoney(),account.getAccountId());
}
@Override
public void delete(int id) {
jdbcTemplate.update("delete from account where accountId=?",id);
}
@Override
public List<Account> findAll() {
return jdbcTemplate.query("select * from account",new BeanPropertyRowMapper<>(Account.class));
}
}
6.5 service层
6.5.1 service接口
public interface IAccountService {
//添加
void save(Account account);
//更新
void update(Account account);
//删除
void delete(int id);
//查询
List<Account> findAll();
}
6.5.2 service实现类
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao;
/*使用SpringIOC容器注入dao对象,提供set方法*/
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void save(Account account) {
accountDao.save(account);
}
@Override
public void update(Account account) {
accountDao.update(account);
}
@Override
public void delete(int id) {
accountDao.delete(id);
@Override
public List<Account> findAll() {
return accountDao.findAll();
}
}
6.6 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1.创建连接池对象-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf8"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--2.创建jdbcTemplate对象,注入连接池对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--3.创建dao对象,注入jdbcTemplate对象-->
<bean id="accountDao" class="com.azure.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--4.创建service对象,注入dao对象-->
<bean id="accountService" class="com.azure.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
</beans>
6.7 测试类
public class WebApp {
/*测试类中创建容器获取service对象*/
private ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
private IAccountService accountService = (IAccountService) ac.getBean("accountService");
@Test
public void save() {
Account account = new Account();
account.setUid(46);
account.setMoney(99D);
accountService.save(account);
}
@Test
public void update() {
Account account = new Account();
account.setAccountId(1);
account.setUid(46);
account.setMoney(99D);
accountService.update(account);
}
@Test
public void delete() {
accountService.delete(4);
}
@Test
public void findAll() {
System.out.println(accountService.findAll());
}
}
6.8 bean配置文件优化
将数据库连接设置放在jdbc.properties中,bean.xml里面加载文件。
- 方便修改数据库连接,同时保证账户信息安全
- 使用标签
<context:>
标签加载properties文件;注意写法 - 在连接池配置中使用${}获取配置文件中指定key的value值
<?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/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--加载jdbc.properties配置文件-->
<!--注意整个语句的写法-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--1.创建连接池对象-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--使用${key}根据指定key在properties文件中获取对应的值}-->
<property name="driverClassName" value="${jdbc.driver}}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--2.创建jdbcTemplate对象,注入连接池对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--3.创建dao对象,注入jdbcTemplate对象-->
<bean id="accountDao" class="com.azure.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!--4.创建service对象,注入dao对象-->
<bean id="accountService" class="com.azure.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
</beans>