Spring_01

Spring概述

Spring是分层的Java2E应用full-stack轻量级开源框架,,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。

spring的体系结构

程序的耦合和解耦

​ 在软件工程中,耦合指的就是就是对象之间的依赖性。

​ 耦合是影响软件复杂程度和设计质量的一个重要因素,在设计上我们应采用以下原则:如果模块间必须存在耦合,就尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,尽量避免使用内容耦合。

​ 在进行软件设计时,应力争做到高内聚,低耦合。


解决程序耦合的思路一:反射

当是我们讲解jdbc时,是通过反射来注册驱动的,代码如下:

Class.*forName*("com.mysql.jdbc.Driver");//此处只是一个字符串

此时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除mysql的驱动jar包,依然可以编译(运行就不要想了,没有驱动不可能运行成功的)。

同时,也产生了一个新的问题,mysql驱动的全限定类名字符串是在java类中写死的,一旦要改还是要修改源码。

解决这个问题也很简单,使用配置文件配置(xml或者是properties)。


解决程序耦合的思路二:工厂模式解耦

在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象同时创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。

那么,这个读取配置文件,创建和获取三层对象的类就是工厂。


控制反转-Inversion Of Control(IOC)

​ 先解释下工厂 → 工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。而不是我们在程序中去new对象,而是通过工厂去创建对象,并且通过工厂去获取对象。

原来:

我们在获取对象时,都是采用new的方式。是主动的

现在:

我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。

这种被动接收的方式获取对象的思想就是控制反转(IOC),它是spring框架的核心之一。

明确ioc的作用: 削减计算机程序的耦合(解除我们代码中的依赖关系),将对象的创建和调用都交给spring容器去处理。

使用spring的IOC解决程序耦合

官网:http://spring.io/

下载地址:

http://repo.springsource.org/libs-release-local/org/springframework/spring

解压:(Spring目录结构:)

  • docs :API和开发规范.
  • libs :jar包和源码.
  • schema :约束.

初始案例(最常用的方法)

导入依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.it</groupId>
  7. <artifactId>spring_day01_ioc</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <dependencies>
  10. <dependency>
  11. <groupId>org.springframework</groupId>
  12. <artifactId>spring-context</artifactId>
  13. <version>5.0.2.RELEASE</version>
  14. </dependency>
  15. </dependencies>
  16. </project>

创建Dao

创建接口AccountDao.java

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao {
  5. /**
  6. * 模拟保存账户
  7. */
  8. void saveAccount();
  9. }

创建实现类AccountDaoImpl.java

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl implements AccountDao {
  5. public void saveAccount(){
  6. System.out.println("AccountDaoImpl实现了AccountDao的接口");
  7. }
  8. }

创建Service 
创建接口AccountService.java

  1. /**
  2. * 账户业务层的接口
  3. */
  4. public interface AccountService {
  5. /**
  6. * 模拟保存账户
  7. */
  8. void saveAccount();
  9. }

创建接口的实现类AccountServiceImpl.java

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. public class AccountServiceImpl implements AccountService {
  5. private AccountDao accountDao ;
  6. public AccountServiceImpl(){
  7. System.out.println("对象创建了");
  8. }
  9. public void saveAccount(){
  10. System.out.println("AccountServiceImpl实现了AccountService接口");
  11. accountDao.saveAccount();
  12. }
  13. }

在resource下创建applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!--把对象的创建交给spring来管理-->
  7. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl"></bean>
  8. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl"></bean>
  9. </beans>

新建测试类:

  1. /**
  2. * 模拟一个表现层,用于调用业务层
  3. */
  4. public class Client {
  5. // 模拟Action
  6. /**
  7. * 测试由ApplicationContext对象获取spring容器中创建的对象
  8. * @param args
  9. */
  10. public static void main(String[] args) {
  11. // 代码之间存在依赖关系(耦合)
  12. // AccountService accountService = new AccountServiceImpl();
  13. // 由spring创建对象(完成对象的解耦)
  14. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  15. // 通过名称调用(通过spring容器中的id属性)(推荐)
  16. AccountService accountService = (AccountService) ac.getBean("accountService");
  17. //通过类型调用(通过spring容器中的class属性)
  18. AccountService accountService = ac.getBean(AccountServiceImpl.class);
  19. accountService.saveAccount();
  20. }

其中涉及到(ApplicationContext和ClassPathXmlApplicationContext、FileSystemXmlApplicationContex的关系)↓↓↓↓

【ApplicationContext 接口的实现类 】

(1)ClassPathXmlApplicationContext: (重点)

它是从类的根路径下加载配置文件 推荐使用这种

(2)FileSystemXmlApplicationContext:

它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。

(3)AnnotationConfigApplicationContext:

当我们使用注解配置容器对象时,需要使用此类来创建spring 容器。它用来读取注解。


测试BeanFactory和ApplicationContext之间的区别

  • ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。(立即加载)
  • BeanFactory:什么时候使,用什么时候创建对象。(延迟加载)
  1. public static void main(String[] args) {
  2. // 使用ApplicationContext创建对象默认是单例(只要加载spring容器,对象会立即创建,叫做立即检索)
  3. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  4. AccountService accountService1 = (AccountService) ac.getBean("accountService");
  5. System.out.println(accountService1);
  6. }
  1. public static void main(String[] args) {
  2. // 使用BeanFactory创建对象默认是单例(当加载spring容器的时候,不会执行构造方法,对象不会立即创建,只要调用getBean的方法,对象才会创建,叫做延迟检索)
  3. BeanFactory ac = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
  4. AccountService accountService = (AccountService) ac.getBean("accountService");
  5. System.out.println(accountService);
  6. }

【ApplicationContext 接口的实现类 】

(1)ClassPathXmlApplicationContext: 
它是从类的根路径下加载配置文件 ( 推荐使用这种 
)

(2)FileSystemXmlApplicationContext: 
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。注意磁盘的权限

(3)AnnotationConfigApplicationContext: 
当我们使用注解配置容器对象时,需要使用此类来创建spring 容器。它用来读取注解。

  1. public static void main(String[] args) {
  2. // 测试ClassPathXmlApplicationContext
  3. // ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  4. // 测试FileSystemXmlApplicationContext
  5. ApplicationContext ac = new FileSystemXmlApplicationContext("d:/applicationContext.xml");
  6. AccountService accountService = (AccountService) ac.getBean("accountService");
  7. System.out.println(accountService);
  8. AccountService accountService1 = (AccountService) ac.getBean("accountService");
  9. System.out.println(accountService1);
  10. }

id和name的配置

id中不能出现特殊字符(容器中的唯一标识),name中可以出现特殊的字符(表示引用)。

可以指定多个name,之间可以用分号(“;”)、空格(“ ”)或逗号(“,”)分隔开,如果没有指定id,那么第一个name为标识符,其余的为别名; 若指定了id属性,则id为标识符,所有的name均为别名。如:

<bean name="alias1 alias2;alias3,alias4" id="hello1" class="com.zyh.spring3.hello.HelloWorld"> </bean>

此时,hello1为标识符,而alias1,alias2,alias3,alias4为别名,它们都可以作为Bean的键值;


另外两种工厂的使用方式

采用静态工厂实例化的方式

applicationContext.xml

  1. <!-- 第二种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器) -->
  2. <bean id="accountService" class="com.it.factory.StaticFactory" factory-method="getAccountService"></bean>

AccountServiceImpl.java

  1. public class AccountServiceImpl implements AccountService {
  2. }

StaticFactory.java →静态工厂类

  1. /**
  2. * 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
  3. */
  4. public class StaticFactory {
  5. //这里容易↓忽略的点
  6. public static AccountService getAccountService(){
  7. return new AccountServiceImpl();
  8. }
  9. }

采用实例工厂(非静态的)实例化的方式

applicationContext.xml

  1. <!-- 第三种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器) -->
  2. <bean id="instanceFactory" class="com.it.factory.InstanceFactory"></bean>
  3. <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

AccountServiceImpl.java

  1. public class AccountServiceImpl implements AccountService {
  2. }

StaticFactory.java →静态工厂类

  1. /**
  2. * 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
  3. */
  4. public class StaticFactory {
  5. //非静态↓
  6. public AccountService getAccountService(){
  7. return new AccountServiceImpl();
  8. }
  9. }

Bean的作用访问的配置:scope的配置

Spring创建这个类的时候,默认采用的单例的模式进行创建的。如果想去改变单例模式,需要通过scope进行配置。

Scope属性中有以下几个取值:

  • singleton :默认值,单例的。

  • prototype :多例的。

  • request :应用在web应用中,将创建的对象存入到request域中。

  • session :应用在web应用中,将创建的对象存入到session域中。

  • globalsession :应用在集群环境下使用。将创建的对象存入到全局的session中。

    applicationContext.xml中的配置

  1. <!-- bean的作用范围调整
  2. bean标签的scope属性:
  3. 作用:用于指定bean的作用范围
  4. 取值: 常用的就是单例的和多例的
  5. singleton:单例的(默认值)
  6. prototype:多例的
  7. request:作用于web应用的请求范围
  8. session:作用于web应用的会话范围
  9. global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
  10. -->
  11. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl" scope="prototype"></bean>


Bean的生命周期的配置

单例对象

  • 出生:当容器创建时对象出生

  • 活着:只要容器还在,对象一直活着

  • 死亡:容器销毁,对象消亡

  • 总结:单例对象的生命周期和容器相同

多例对象

  • 出生:当我们使用对象时spring框架为我们创建

  • 活着:对象只要是在使用过程中就一直活着。

  • 死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收

  • 总结:多例对象的生命周期和对象是否被使用有关。与容器是否被销毁无关。

AccountServiceImpl.java

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. public class AccountServiceImpl implements AccountService {
  5. public AccountServiceImpl(){
  6. System.out.println("对象创建了");
  7. }
  8. public void saveAccount(){
  9. System.out.println("service中的saveAccount方法执行了。。。");
  10. }
  11. public void init(){
  12. System.out.println("对象初始化了。。。");
  13. }
  14. public void destroy(){
  15. System.out.println("对象销毁了。。。");
  16. }
  17. }

applicationContext.xml

  1. <!-- bean对象的生命周期
  2. 单例对象
  3. 出生:当容器创建时对象出生
  4. 活着:只要容器还在,对象一直活着
  5. 死亡:容器销毁,对象消亡
  6. 总结:单例对象的生命周期和容器相同
  7. 多例对象
  8. 出生:当我们使用对象时spring框架为我们创建
  9. 活着:对象只要是在使用过程中就一直活着。
  10. 死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
  11. 总结:多例对象的声明周期和对象是否被使用有关
  12. -->
  13. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl"
  14. scope="singleton" init-method="init" destroy-method="destroy"></bean>

Client.java测试:

  1. /**
  2. * 模拟一个表现层,用于调用业务层
  3. */
  4. public class Client {
  5. /**
  6. *
  7. * @param args
  8. */
  9. public static void main(String[] args) {
  10. //1.获取核心容器对象(子类:applicationContext 没有close方法)
  11. ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  12. //2.根据id获取Bean对象
  13. AccountService as = (AccountService)ac.getBean("accountService");
  14. as.saveAccount();
  15. //手动关闭容器(单例的时候,关闭才有效果)
  16. ac.close();
  17. }
  18. }

总结:开发场景

单例(常用):一般创建对象单例(例如Service对象、Dao对象,数据源的对象…)

多例:如果spring创建数据库连接对象Connection(每个线程使用的数据库连接对象是不同的,保证线程安全)

​ Struts2(本身多实例,多线程),如果spring创建struts2的对象,一定是多例(了解)


spring的依赖注入(DI)

简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。 这就是依赖注入。

依赖注入: 
能注入的数据:有三类

  • (1)基本类型和String类型(值的注入)

  • (2)其他bean对象类型(在配置文件中或者注解配置过的bean)(对象的注入)

  • (3)复杂类型/集合类型(集合的注入)

能注入的方式:有三种

  • (1)第一种:使用构造函数提供

  • (2)第二种:使用set方法提供(使用p名称空间注入)(用的最多)

  • (3)第三种:使用注解提供(明天的内容)

创建包com.it.service,创建接口AccountService.java

  1. /**
  2. * 账户业务层的接口
  3. */
  4. public interface AccountService {
  5. /**
  6. * 模拟保存账户
  7. */
  8. void saveAccount();
  9. }

创建包com.it.service.impl,创建接口的实现类AccountServiceImpl.java

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. public class AccountServiceImpl implements AccountService {
  5. private String name;
  6. private Integer age;
  7. private Date birthday;
  8. public void saveAccount(){
  9. System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
  10. }
  11. }

构造函数注入

AccountServiceImpl.java提供传递参数的构造方法

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. public class AccountServiceImpl implements AccountService {
  5. //如果是经常变化的数据,并不适用于注入的方式
  6. private String name;
  7. private Integer age;
  8. private Date birthday;
  9. public AccountServiceImpl(){
  10. }
  11. public AccountServiceImpl(String name,Integer age,Date birthday){
  12. this.name = name;
  13. this.age = age;
  14. this.birthday = birthday;
  15. }
  16. public void saveAccount(){
  17. System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
  18. }
  19. }

applicationContext.xml

  1. <!--构造函数注入:
  2. 使用的标签:constructor-arg
  3. 标签出现的位置:bean标签的内部
  4. 标签中的属性
  5. type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
  6. index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
  7. name:用于指定给构造函数中指定名称的参数赋值 常用的
  8. =============以上三个用于指定给构造函数中哪个参数赋值===============================
  9. value:用于提供基本类型和String类型的数据
  10. ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
  11. 优势:
  12. 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
  13. 弊端:
  14. 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
  15. -->
  16. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  17. <constructor-arg name="name" value="泰斯特"></constructor-arg>
  18. <constructor-arg name="age" value="18"></constructor-arg>
  19. <constructor-arg name="birthday" ref="now"></constructor-arg>
  20. </bean>
  21. <!-- 配置一个日期对象 -->
  22. <bean id="now" class="java.util.Date"></bean>

测试类Client.java

  1. /**
  2. * 模拟一个表现层,用于调用业务层
  3. */
  4. public class Client {
  5. public static void main(String[] args) {
  6. //1.获取核心容器对象
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //2.根据id获取Bean对象
  9. AccountService as = (AccountService)ac.getBean("accountService");
  10. as.saveAccount();
  11. }
  12. }

set方法注入 (推荐使用)

AccountServiceImpl2.java提供属性的set方法。

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. public class AccountServiceImpl2 implements AccountService {
  5. //如果是经常变化的数据,并不适用于注入的方式
  6. private String name;
  7. private Integer age;
  8. private Date birthday;
  9. public void setName(String name) {
  10. this.name = name;
  11. }
  12. public void setAge(Integer age) {
  13. this.age = age;
  14. }
  15. public void setBirthday(Date birthday) {
  16. this.birthday = birthday;
  17. }
  18. public void saveAccount(){
  19. System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
  20. }
  21. }

applicationContext.xml

  1. <!-- set方法注入 更常用的方式
  2. 涉及的标签:property
  3. 出现的位置:bean标签的内部
  4. 标签的属性
  5. name:用于指定注入时所调用的set方法名称
  6. value:用于提供基本类型和String类型的数据
  7. ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
  8. 优势:
  9. 1:使用set方法创建对象时没有明确的限制,可以直接使用默认构造函数;
  10. 2:使用set方法注入值或者对象,需要哪个属性只需要注入哪个属性
  11. -->
  12. <bean id="accountService2" class="com.it.service.impl.AccountServiceImpl2">
  13. <property name="name" value="小明" ></property>
  14. <property name="age" value="21"></property>
  15. <property name="birthday" ref="now"></property>
  16. </bean>
  17. <!-- 配置一个日期对象 -->
  18. <bean id="now" class="java.util.Date"></bean>

测试类Client.java

  1. public class Client {
  2. public static void main(String[] args) {
  3. //1.获取核心容器对象
  4. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  5. //2.根据id获取Bean对象
  6. AccountService as = (AccountService)ac.getBean("accountService2");
  7. as.saveAccount();
  8. }
  9. }

使用p名称空间注入数据(本质还是调用set方法) (了解)

p名称空间作用:简化set方法依赖注入

l引入p名称空间

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:p="http://www.springframework.org/schema/p"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">

使用p名称空间完成属性注入

语法:普通属性 p:属性名=" " 对象类型 p:属性名-ref=" "

  1. <!--
  2. 使用p空间完成注入
  3. 语法:普通属性 p:属性名=”” 对象类型 p:属性名-ref=””
  4. -->
  5. <bean id="accountService2" class="com.it.service.impl.AccountServiceImpl2" p:name="小刚" p:age="25" p:birthday-ref="now"></bean>
  6. <!-- 配置一个日期对象 -->
  7. <bean id="now" class="java.util.Date"></bean>

这里注意:需要对属性提供set方法,方可实现注入。


注入集合属性(复杂类型)

AccountServiceImpl3.java提供属性的set方法

  1. /**
  2. * 账户的业务层实现类
  3. */
  4. public class AccountServiceImpl3 implements AccountService {
  5. Object[] arrays;
  6. List<Object> list;
  7. Set<Object> set;
  8. Map<String,Object> map;
  9. Properties properties;
  10. public void setArrays(Object[] arrays) {
  11. this.arrays = arrays;
  12. }
  13. public void setList(List<Object> list) {
  14. this.list = list;
  15. }
  16. public void setSet(Set<Object> set) {
  17. this.set = set;
  18. }
  19. public void setMap(Map<String, Object> map) {
  20. this.map = map;
  21. }
  22. public void setProperties(Properties properties) {
  23. this.properties = properties;
  24. }
  25. public void saveAccount() {
  26. System.out.println("执行AccountServiceImpl中的saveAccount方法! arrays:"+Arrays.toString(arrays)+" list:"+list+" set:"+set+" map:"+map+" properties"+properties);
  27. }
  28. }

applicationContext.xml

  1. <!-- 复杂类型的注入/集合类型的注入
  2. 用于给List结构集合注入的标签:
  3. list array set
  4. 用于个Map结构集合注入的标签:
  5. map props
  6. 结构相同,标签可以互换
  7. -->
  8. <bean id="accountService3" class="com.it.service.impl.AccountServiceImpl3">
  9. <!--数组-->
  10. <!--在spring的集合注入中,array,list,set是可以通用的-->
  11. <property name="arrays">
  12. <set>
  13. <value>张三</value>
  14. <value></value>
  15. <ref bean="date"></ref>
  16. </set>
  17. </property>
  18. <!--list集合-->
  19. <property name="list">
  20. <set>
  21. <value>李四</value>
  22. <value></value>
  23. <ref bean="date"></ref>
  24. </set>
  25. </property>
  26. <!--set集合-->
  27. <property name="set">
  28. <set>
  29. <value>王五</value>
  30. <value></value>
  31. <ref bean="date"></ref>
  32. </set>
  33. </property>
  34. <!--map集合-->
  35. <property name="map">
  36. <map>
  37. <entry key="key001">
  38. <value>赵六</value>
  39. </entry>
  40. <entry key="key002" value="23"></entry>
  41. <entry key="key003">
  42. <ref bean="date"></ref>
  43. </entry>
  44. </map>
  45. </property>
  46. <!--properties集合,和map集合很相似,也是键值对,键和值只能是String-->
  47. <!--集合属性的应用场景:初始化系统中使用常量-->
  48. <property name="properties">
  49. <props>
  50. <prop key="driver">com.mysql.jdbc.Driver</prop>
  51. <prop key="url">jdbc:mysql:///itcastspring</prop>
  52. <prop key="username">root</prop>
  53. <prop key="password">root</prop>
  54. </props>
  55. </property>
  56. <bean id="date" class="java.util.Date"></bean>
  57. </bean>

测试类Client.java

  1. public class Client {
  2. public static void main(String[] args) {
  3. //1.获取核心容器对象
  4. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  5. //2.根据id获取Bean对象
  6. AccountService as = (AccountService)ac.getBean("accountService3");
  7. as.saveAccount();
  8. }
  9. }

在Service中,注入Dao

我们的业务层仍会调用持久层的方法。

applicationContext.xml

  1. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  2. <property name="accountDao" ref="accountDao"></property>
  3. </bean>
  4. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl"></bean>
  1. public class AccountServiceImpl implements AccountService {
  2. AccountDao accountDao;
  3. // 注入:set方法,构造方法
  4. public void setAccountDao(AccountDao accountDao) {
  5. this.accountDao = accountDao;
  6. }
  7. }

Spring_One的更多相关文章

随机推荐

  1. 各个版本 Windows 10 系统中自带的 .NET Framework 版本

    原文各个版本 Windows 10 系统中自带的 .NET Framework 版本 Windows 名称 Windows 版本 自带的 .NET Framework 版本 Windows 10 Oc ...

  2. Qt控件焦点切换

    们日常切换控件,例如QQ登陆的账号和密码输入框就可以通过Tab键切换焦点.  图1 qq切换焦点 Qt中QWidget提供了一个静态方式实现该效果 其中也包含介绍使用 [static] void QW ...

  3. 使用Adorner显示WPF控件的边界点

    原文:使用Adorner显示WPF控件的边界点 当我们拖动WPF控件时,我们为了更清楚地需要显示控件,一般我们会在WPF控件所围成的矩形区域的四个边界点上作一个特殊的记号(比如圆点).如下图: 在Wi ...

  4. poj 3390 Print Words in Lines 动态规划

    意甲冠军: 给n每行长度和字符可放置最大数量字m,每一行产生值至(m-x)^2,x是一个字符上线人数(包含空话之间格).为了让所有的完成,产生的话值最小和. 分析: 动态规划非常重要的就是状态的定义, ...

  5. MATLAB利用散点进行函数曲线拟合

    原文:MATLAB利用散点进行函数曲线拟合 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/laobai1015/article/details/77 ...

  6. 关于hibernate一对一配置

    实体类关系 一对一 一对多 多对一 多对多 Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射.下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方式分 ...

  7. QWidget继承自QPaintDevice,这样就可以直接把QWidget传入QPainter的构造函数,比如QPainter(mylabel),然后设置QWidget的长宽后直接进行作画了

    比如用QLabel在主界面上画两条虚线: bool ContentWidget::eventFilter(QObject *obj, QEvent *event) { if(obj == line_l ...

  8. QT 窗体控件的透明度设置(三种方法)

    整个窗体 当设置QT的窗体(QMainWindow, QDialog)时,直接用 targetForm->setWindowOpacity()   函数即可实现,效果为窗体及窗体内所有控件都透明 ...

  9. 用MVVM模式开发中遇到的零散问题总结(3)——自制正则表达式万能绑定转换器

    原文:用MVVM模式开发中遇到的零散问题总结(3)--自制正则表达式万能绑定转换器 前言 最近接受了3个项目的洗礼,出差近3个月,各种北京.广州.昆明来回奔波,好久没写博客了,之前我觉得我遇到的问题都 ...

  10. linux服务脚本编写

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...