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"?>
    1. <project xmlns="http://maven.apache.org/POM/4.0.0"
    1. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    1. <modelVersion>4.0.0</modelVersion>
    1. <groupId>com.it</groupId>
    1. <artifactId>spring_day01_ioc</artifactId>
    1. <version>1.0-SNAPSHOT</version>
    1. <dependencies>
    1. <dependency>
    1. <groupId>org.springframework</groupId>
    1. <artifactId>spring-context</artifactId>
    1. <version>5.0.2.RELEASE</version>
    1. </dependency>
    1. </dependencies>
    1. </project>

创建Dao

创建接口AccountDao.java

    1. /**
    1. * 账户的持久层接口
    1. */
    1. public interface AccountDao {
    1. /**
    1. * 模拟保存账户
    1. */
    1. void saveAccount();
    1. }

创建实现类AccountDaoImpl.java

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

创建Service 
创建接口AccountService.java

    1. /**
    1. * 账户业务层的接口
    1. */
    1. public interface AccountService {
    1. /**
    1. * 模拟保存账户
    1. */
    1. void saveAccount();
    1. }

创建接口的实现类AccountServiceImpl.java

    1. /**
    1. * 账户的业务层实现类
    1. */
    1. public class AccountServiceImpl implements AccountService {
    1. private AccountDao accountDao ;
    1. public AccountServiceImpl(){
    1. System.out.println("对象创建了");
    1. }
    1. public void saveAccount(){
    1. System.out.println("AccountServiceImpl实现了AccountService接口");
    1. accountDao.saveAccount();
    1. }
    1. }

在resource下创建applicationContext.xml

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

新建测试类:

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

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

ApplicationContext 接口的实现类 】

(1)ClassPathXmlApplicationContext: (重点)

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

2)FileSystemXmlApplicationContext

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

3AnnotationConfigApplicationContext:

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


测试BeanFactory和ApplicationContext之间的区别

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

【ApplicationContext 接口的实现类 】

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

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

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

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

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容器) -->
    1. <bean id="accountService" class="com.it.factory.StaticFactory" factory-method="getAccountService"></bean>

AccountServiceImpl.java

    1. public class AccountServiceImpl implements AccountService {
    1. }

StaticFactory.java →静态工厂类

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

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

applicationContext.xml

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

AccountServiceImpl.java

    1. public class AccountServiceImpl implements AccountService {
    1. }

StaticFactory.java →静态工厂类

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

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

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

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

  • singleton :默认值,单例的。

  • prototype :多例的。

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

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

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

    applicationContext.xml中的配置

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


Bean的生命周期的配置

单例对象

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

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

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

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

多例对象

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

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

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

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

AccountServiceImpl.java

    1. /**
    1. * 账户的业务层实现类
    1. */
    1. public class AccountServiceImpl implements AccountService {
    1. public AccountServiceImpl(){
    1. System.out.println("对象创建了");
    1. }
    1. public void saveAccount(){
    1. System.out.println("service中的saveAccount方法执行了。。。");
    1. }
    1. public void init(){
    1. System.out.println("对象初始化了。。。");
    1. }
    1. public void destroy(){
    1. System.out.println("对象销毁了。。。");
    1. }
    1. }

applicationContext.xml

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

Client.java测试:

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

总结:开发场景

单例(常用):一般创建对象单例(例如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. /**
    1. * 账户业务层的接口
    1. */
    1. public interface AccountService {
    1. /**
    1. * 模拟保存账户
    1. */
    1. void saveAccount();
    1. }

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

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

构造函数注入

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

    1. /**
    1. * 账户的业务层实现类
    1. */
    1. public class AccountServiceImpl implements AccountService {
    1. //如果是经常变化的数据,并不适用于注入的方式
    1. private String name;
    1. private Integer age;
    1. private Date birthday;
    1. public AccountServiceImpl(){
    1. }
    1. public AccountServiceImpl(String name,Integer age,Date birthday){
    1. this.name = name;
    1. this.age = age;
    1. this.birthday = birthday;
    1. }
    1. public void saveAccount(){
    1. System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
    1. }
    1. }

applicationContext.xml

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

测试类Client.java

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

set方法注入 (推荐使用)

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

    1. /**
    1. * 账户的业务层实现类
    1. */
    1. public class AccountServiceImpl2 implements AccountService {
    1. //如果是经常变化的数据,并不适用于注入的方式
    1. private String name;
    1. private Integer age;
    1. private Date birthday;
    1. public void setName(String name) {
    1. this.name = name;
    1. }
    1. public void setAge(Integer age) {
    1. this.age = age;
    1. }
    1. public void setBirthday(Date birthday) {
    1. this.birthday = birthday;
    1. }
    1. public void saveAccount(){
    1. System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
    1. }
    1. }

applicationContext.xml

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

测试类Client.java

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

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

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

l引入p名称空间

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

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

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

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

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


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

AccountServiceImpl3.java提供属性的set方法

    1. /**
    1. * 账户的业务层实现类
    1. */
    1. public class AccountServiceImpl3 implements AccountService {
    1. Object[] arrays;
    1. List<Object> list;
    1. Set<Object> set;
    1. Map<String,Object> map;
    1. Properties properties;
    1. public void setArrays(Object[] arrays) {
    1. this.arrays = arrays;
    1. }
    1. public void setList(List<Object> list) {
    1. this.list = list;
    1. }
    1. public void setSet(Set<Object> set) {
    1. this.set = set;
    1. }
    1. public void setMap(Map<String, Object> map) {
    1. this.map = map;
    1. }
    1. public void setProperties(Properties properties) {
    1. this.properties = properties;
    1. }
    1. public void saveAccount() {
    1. System.out.println("执行AccountServiceImpl中的saveAccount方法! arrays:"+Arrays.toString(arrays)+" list:"+list+" set:"+set+" map:"+map+" properties"+properties);
    1. }
    1. }

applicationContext.xml

    1. <!-- 复杂类型的注入/集合类型的注入
    1. 用于给List结构集合注入的标签:
    1. list array set
    1. 用于个Map结构集合注入的标签:
    1. map props
    1. 结构相同,标签可以互换
    1. -->
    1. <bean id="accountService3" class="com.it.service.impl.AccountServiceImpl3">
    1. <!--数组-->
    1. <!--在spring的集合注入中,array,list,set是可以通用的-->
    1. <property name="arrays">
    1. <set>
    1. <value>张三</value>
    1. <value></value>
    1. <ref bean="date"></ref>
    1. </set>
    1. </property>
    1. <!--list集合-->
    1. <property name="list">
    1. <set>
    1. <value>李四</value>
    1. <value></value>
    1. <ref bean="date"></ref>
    1. </set>
    1. </property>
    1. <!--set集合-->
    1. <property name="set">
    1. <set>
    1. <value>王五</value>
    1. <value></value>
    1. <ref bean="date"></ref>
    1. </set>
    1. </property>
    1. <!--map集合-->
    1. <property name="map">
    1. <map>
    1. <entry key="key001">
    1. <value>赵六</value>
    1. </entry>
    1. <entry key="key002" value="23"></entry>
    1. <entry key="key003">
    1. <ref bean="date"></ref>
    1. </entry>
    1. </map>
    1. </property>
    1. <!--properties集合,和map集合很相似,也是键值对,键和值只能是String-->
    1. <!--集合属性的应用场景:初始化系统中使用常量-->
    1. <property name="properties">
    1. <props>
    1. <prop key="driver">com.mysql.jdbc.Driver</prop>
    1. <prop key="url">jdbc:mysql:///itcastspring</prop>
    1. <prop key="username">root</prop>
    1. <prop key="password">root</prop>
    1. </props>
    1. </property>
    1. <bean id="date" class="java.util.Date"></bean>
    1. </bean>

测试类Client.java

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

在Service中,注入Dao

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

applicationContext.xml

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

Spring_One的更多相关文章

随机推荐

  1. Information centric network (icn) node based on switch and network process using the node

    The present invention relates to an apparatus for supporting information centric networking. An info ...

  2. 【HLSL学习笔记】WPF Shader Effect Library算法解读之[BandedSwirl]

    原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[BandedSwirl] 因工作原因,需要在Silverlight中使用Pixel Shader技术,这对于我来 ...

  3. Open SSL 开发环境配置

    Open SSL 开发环境配置 最后更新日期:2014-05-13 阅读前提:VisualStudio的基本使用.Cent OS的基本使用 环境: Windows 8.1 64bit英文版,Visua ...

  4. Notepad++ 自定义关键字

    Notepad++是一款輕便好用的編輯器,但可能有些語言的關鍵字不全,比方SQL中,默認關鍵字沒有Merge. 怎样給Notepad++中的語言添加關鍵字,而不是大動干戈自定義一個語言? 步驟: Se ...

  5. matlab 求解 Ax=B 时所用算法

    x = A\B; x = mldivide(A, B); matlab 在这里的求解与严格的数学意义是不同的, 如果 A 接近奇异,matlab 仍会给出合理的结果,但也会提示警告信息: 如果 A 为 ...

  6. ios-利用键盘通知处理键盘出现时遮挡控件问题

    -(void)viewDidLoad { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; //注册键盘显示通知 ...

  7. jupyter_远程安装&问题

    安装: https://jupyter.readthedocs.io/en/latest/install.html#install 配置 Ubuntu 16.04 LTS 配置 Jupyter not ...

  8. maven_默认新建项目jdk1.6_默认配置

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  9. Why aren't more desktop apps written with Qt?(quora.com系列文章)

    As far as I know and have understood in my experience with Qt, it's a very good and easy to learn li ...

  10. WPF VisualTreeHelper的使用

    <Window x:Class="MyWpf.MainWindow"        xmlns="http://schemas.microsoft.com/winf ...