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

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

3AnnotationConfigApplicationContext:

当我们使用注解配置容器对象时,需要使用此类来创建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. Android开发小知识

    修改Android app图标(Android Studio) 1.  res\drawable 放置icon.png(此图片是你需要修改的图标); 2.  修改AndroidManifest.xml ...

  2. delphi xe 之路(14)使用FireMonkeyStyle(一共30篇)

    FireMonkey使用Style来控制控件的显示方式. 每个控件都有一个StyleLookup属性,FireMonkey就是通过控件的这个属性来在当前窗体的StyleBook控件中查找匹配的Styl ...

  3. 简明Python3教程 16.标准库

    简介 python标准库作为python标准安装的一部分,其自身包含数量庞大的实用模块, 因此熟悉python标准库非常重要,因为很多问题都能利用python标准库快速解决. 下面我们将研究标准库中的 ...

  4. PMP项目经理认证

    PMP认证是由美国项目管理学会(PMI)在全球范围内推出的针对项目经理的资格认证体系,通过该认证的项目经理叫"PMP",即Project Management Profession ...

  5. (转)总结:JavaScript异步、事件循环与消息队列、微任务与宏任务

    前言 Philip Roberts 在演讲 great talk at JSConf on the event loop 中说:要是用一句话来形容 JavaScript,我可能会这样: “JavaSc ...

  6. C++ string的那些坑,C++ string功能补充(类型互转,分割,合并,瘦身) ,c++ string的内存本质(简单明了的一个测试)

    1. size_type find_first_of( const basic_string &str, size_type index = 0 ); 查找在字符串中第一个与str中的某个字符 ...

  7. Golang写https服务端

    1. 生成私钥openssl genrsa -out key.pem 20482. 生成证书openssl req -new -x509 -key key.pem -out cert.pem -day ...

  8. sql Left right join 多表 注意表的连接顺序

    多表左/右连接,表的连接顺序也可以影响查询速度 左连接时,应该把小表放在前面连接例子:A.B.C三表左连接情况1:A先和B连接,得到100条记录100条记录再和C左连接情况2:A先和C连接,得到50条 ...

  9. 绕过010Editor网络验证(用python做一个仿真http server真容易,就几行代码)

    010Editor是一款非常强大的十六进制编辑器,尤其是它的模板功能在分析文件格式时相当好用!网上现在也有不少010Editor的破解版,如果没钱或者舍不得花钱买授权的话,去官方下载安装包再使用注册机 ...

  10. C++成员函数指针错误用法警示(成员函数指针与高性能的C++委托,三篇),附好多评论

    今天做一个成绩管理系统的并发引擎,用Qt做的,仿照QtConcurrent搞了个模板基类.这里为了隐藏细节,隔离变化,把并发的东西全部包含在模板基类中.子类只需注册需要并发执行的入口函数即可在单独线程 ...