(一)发展历史

现在我们有三个层了,可是每层之间的调用是怎样的呢?比如显示层的struts需要调用一个业务类,就需要new一个业务类出来,然后使用;业务层需要调用持久层的类,也需要new一个持久层类出来用。通过这种new方式互相调用就是软件开发中最糟糕设计的体现。简单地说,就是调用者依赖被调用者,它们之间形成了强耦合,如果我想在其他地方复用某个类,则这个类依赖的其他类也需要包含。程序就变得很混乱,每个类互相依赖互相调用,复用度极低。如果一个类做了修改,则其他的类也会受到牵连。这时就出现了spring框架。

Spring的作用就是解耦类之间的依赖关系,一个类如果要依赖什么,那就是一个接口。至于如何实现这个接口,这就不重要了。只要拿到一个实现了这个接口的类,就可以轻松的通过xml配置文件把实现类注射到调用接口的那个类里。所有类之间的这种依赖关系就完全通过配置文件的方式替代了。所以,Spring框架最核心的就是所谓的依赖注射和控制反转。

现在的结构是,sturts负责显示层,hibernate负责持久层,spring负责中间的业务层,这个结构是目前国内最流行的javaweb应用程序架构了。另外,由于Spring使用的依赖注射以及AOP(面向方面编程)。所以它的这种内部模式非常优秀,以至于spring自己也实现了一个使用依赖注射的MVC框架,叫做spring MVC,同时为了很好的处理事物,spring集成了hibernate,使事物管理从hibernate的持久层提升到了业务层,使用更加方便和强大。

(二)理解IOC、DI、AOP的概念

Spring核心

IoC: 控制反转,解决程序对象紧密耦合问题(工厂+反射+配置文件),将程序中原来构造对象的权限,交给IoC容器来构造,当程序需要对象时,找IoC容器获取。

AOP:面向切面编程

DI:依赖注入,IoC容器需要为程序提供依赖对象,返回对象一同可以提供(servlet需要service,找IoC容器获取service,service由容器提供,service依赖DAO注入到service中)

附一个简单的小例子:

在eclipse中new一个java project

然后导入需要的jar包:下载地址为:http://download.csdn.net/detail/u014607184/9589548

然后在src目录下新建package,这里命名为:com.myspring,再在包下新建java文件HelloWorld和MainApp。代码如下:

  1. HelloWorld.java如下:
package com.myspring;

public class HelloWorld {
private String message;
    //依赖注入
public void setMessage(String message)
{
this.message=message; }
public void getMessage()
{
System.out.println("Your Message :"+message);
} }

2. MainApp.java如下:

package com.myspring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp {
public static void main(String[] args)
{//从IoC容器获得对象
     //1、获取IoC容器工厂对象
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
     //2、从IoC容器工厂获取需要对象(根据bean的id获取)
HelloWorld obj =(HelloWorld) context.getBean("helloWorld");
obj.getMessage();
} }

这里需要注意理解的是:

在程序中通过ApplicationContext接口,获取Spring工厂对象。

1.ClassPathXmlApplicationContext读取src下的配置文件

2.FileSystemXmlApplicationContext读取WEB-INF下的配置文件

ApplicationContext是BeanFactory子接口,BeanFactory才是Spring框架最核心工厂接口。

ApplicationContext是对BeanFactory接口扩展,企业开发很少直接使用BeanFactory。

ApplicationContext会在容器初始化时,对其中管理Bean对象进行创建,BeanFactory会在对象获取时才进行初始化。

3. IoC容器装配Bean(xml配置)

方式一:使用类构造器实例化对象

在src目录下创建beans.xml,完整代码如下:

<?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-3.0.xsd">
<bean id="helloWorld" class="com.myspring.HelloWorld">
<property name="message" value="Hello World!" />
</bean>
</beans>

方式二:使用静态工厂静态方法,对对象实例化

<bean id="bean2" class="cn.itcast.spring.b_instance.Bean2Factory" factory-method="getBean2" />

方式三:使用实例工厂实例方法对对象实例化

先实例化工厂:<bean id="bean3Factory" class="cn.itcast.spring.b_instance.Bean3Factory" />

再通过工厂对象的实例方法,构造目标对象: <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3" />

应用场景:大多数情况,可以通过构造器直接实例化,只有在对象构造过程非常复杂的情况下,才会采用工厂实例化的方式。

这里趁热打铁把bean的相关深入一下:

bean的作用域

最常用的singleton和prototype两种

singleton(单例):在一个BeanFactory对象中,引用唯一的一个目标实例

prototype(多例):每次通过工厂执行getBean时,返回不同实例对象

request(请求范围):创建对象保存在request范围,如果request销毁,对象销毁

session(会话范围):创建对象保存在session中,如果session销毁,对象销毁

* globalSession (全局会话 ) :分布式系统,全局会话的概念, 一次登录,应用多个系统

 <!-- 通过scope属性,指定bean作用域 (默认作用域 singleton) -->
<bean id="singletonBean" class="cn.itcast.spring.c_scope.SingletonBean" /><!-- 单例 -->
<bean id="prototypeBean" class="cn.itcast.spring.c_scope.PrototypeBean" scope="prototype"/> <!-- 多例 -->

单例bean在容器初始化时,实例化(只实例化一次)

多例bean在工程执行getbean时,才会实例化(每实例化一次,返回不同对象)

bean的生命周期

可以通过init-method属性配置bean对象初始化执行方法,destory-method属性配置bean对象销毁的方法(初始化方法和构造方法的区别:构造方法作用申请空间,为对象基本属性初始化;初始化方法,对象复杂构造过程,java语言建议将对象复杂构造过程单独抽取)

public class LifeCycleBean implements IHello {
public LifeCycleBean() {
System.out.println("LifeCycleBean 构造...");
} public void setup() {
System.out.println("LifeCycleBean 初始化...");
} public void teardown() {
System.out.println("LifeCycleBean 销毁...");
} @Override
public void sayHello() {
System.out.println("hello ,itcast...");
}
}

  

<bean id="lifeCycleBean" class="cn.itcast.spring.d_lifecycle.LifeCycleBean"
init-method="setup" destroy-method="teardown" />

bean的依赖注入

  1. 构造参数的属性注入
public class Car {
private String name;
private double price; // 为Car类 提供构造方法
public Car(String name, double price) {
super();
this.name = name;
this.price = price;
}

 通过constructor-arg属性进行构造参数注入

<!-- 构造方法属性注入 -->
<bean id="car" class="cn.itcast.spring.e_di.Car">
<!-- 通过constructor-arg 注入构造函数的参数 -->
<!-- index 代表参数顺序 ,第一个参数 0
type 代表参数类型
name 代表参数的名称
value 注入参数的值
ref 引用另一个bean元素的id
-->
<constructor-arg index="0" type="java.lang.String" value="宝马"/>
<constructor-arg index="1" type="double" value="1000000"/>
</bean>

2. setter方法属性注入

public class Employee {
private int id;
private String name; private Car car;// 复杂元素 public void setId(int id) {
this.id = id;
} public void setName(String name) {
this.name = name;
} public void setCar(Car car) {
this.car = car;
}

  在配置文件 使用 元素完成setter属性注入

<!-- setter方法属性注入 -->
<bean id="employee" class="cn.itcast.spring.e_di.Employee" >
<!-- 通过property 注入setter方法属性 (属性名称, 由setter方法推理获得)-->
<!--
name 属性名称 (由setter方法获得)
value 注入参数的值
ref 引用另一个Bean元素的id
-->
<property name="id" value="100001" />
<property name="name" value="张三" />
<!-- 注入复杂对象 -->
<property name="car" ref="car" />
</bean>

  [注意1]:p名称空间的使用

p名称空间,在spring2.5版本后引入,为了简化属性依赖注入(setter方法)

首先,在配置文件,引入p名称空间

xmlns:p="http://www.springframework.org/schema/p"

其次,简化setter方法注入配置

<!-- 使用p命名空间注入 -->
<bean id="employee2" class="cn.itcast.spring.e_di.Employee"
p:eid="100002" p:name="李四" p:car-ref="car"/>

  [注意2]:spEL表达式的使用

在spring3.0之后,引入spEL 表达式语言,简化属性注入 
参考 “Spring_表达式语言.pdf” 学习 
语法: #{表达式} 
用法一: 直接通过value注入,引用一个Bean对象 
用法二: 引用一个Bean对象属性 
用法三: 直接调用对象的方法

public class ValueBean {
private int id = 10003;
private String name = "jor"; public int getId() {
return id;
} public String pickName() {
return name;
}
}

  

<!-- spEL使用 -->
<bean id="valueBean" class="cn.itcast.spring.e_di.ValueBean" />
<bean id="employee3" class="cn.itcast.spring.e_di.Employee" >
<!-- 调用valueBean的getId -->
<property name="eid" value="#{valueBean.id}" />
<!-- 直接调用对象的方法 -->
<property name="name" value="#{valueBean.pickName().toUpperCase()}" />
<!-- #{car} 效果类似 ref -->
<property name="car" value="#{car}" />
</bean>

  

3. 集合元素类型属性注入

spring为每种结合都提供一个元素标签进行注入

public class CollectionBean {
private List<String> list;
private Set<Integer> set;
private Map<String, Integer> map;
private Properties properties; public void setList(List<String> list) {
this.list = list;
} public void setSet(Set<Integer> set) {
this.set = set;
} public void setMap(Map<String, Integer> map) {
this.map = map;
} public void setProperties(Properties properties) {
this.properties = properties;
}

  

<!-- 集合类型属性注入 -->
<bean id="collectionBean" class="cn.itcast.spring.e_di.CollectionBean">
<!--
array 注入数组
list 注入List集合
set 注入Set集合
map 注入Map集合
props 注入 Properties 集合
-->
<property name="list">
<list>
<!--
value 注入基本数据类型, String 类型
ref 注入引用Bean的id
-->
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="set">
<set>
<value>10</value>
<value>10</value>
<value>20</value>
</set>
</property>
<property name="map">
<map>
<!-- map中每个元素都是键值对 -->
<entry key="abc" value="10"></entry>
<entry key="def" value="20"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="qwe123">asd456</prop>
<prop key="tyu567">hjk789</prop>
</props>
</property>
</bean>

  

Eclipse/JavaWeb (三)三大框架之Spring框架 持续更新中...的更多相关文章

  1. 整合SpringMVC框架和Spring框架

    -------------------------siwuxie095                                 整合 SpringMVC 框架和 Spring 框架       ...

  2. 整合Struts2框架和Spring框架

    -----------------------siwuxie095                                 整合 Struts2 框架和 Spring 框架         1 ...

  3. Eclipse/JavaWeb (一)三大框架之struts框架 持续更新中...

    最近主要把javaweb的三大框架过一遍. (一)发展历史 传统的Java Web应用程序是采用JSP+Servlet+Javabean来实现的,这种模式实现了最基本的MVC分层,使得程序分为几层,有 ...

  4. Java框架之spring框架的优点,为什么要学习spring框架

    为什么要学习Spring的框架a: 方便解耦,简化开发    Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理 b:AOP编程的支持      Spring提供面向切 ...

  5. 什么是Spring框架? Spring框架有哪些主要的模块?

    Spring框架是一个为java应用程序的开发提供了综合,广泛的基础性支持的java平台.Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发.Spring框架本身亦是 ...

  6. Java - Struts框架教程 Hibernate框架教程 Spring框架入门教程(新版) sping mvc spring boot spring cloud Mybatis

    https://www.zhihu.com/question/21142149 http://how2j.cn/k/hibernate/hibernate-tutorial/31.html?tid=6 ...

  7. python模块详解 | unittest(单元测试框架)(持续更新中)

    目录: why unittest? unittest的四个重要概念 加载测试用例的三个方法 自动加载测试用例 忽略测试和预期失败 生成html测试报告 why unittest? 简介: Unitte ...

  8. spring web 脚手架 (持续更新中...)

    spring web 脚手架 项目地址: https://github.com/MengW9/scafflod.git 还有觉得哪些可以加上去的配置,欢迎各位拍砖,我会持续更新,大家共同进步 一个通用 ...

  9. ECLIPSE/JAVAWEB (二)三大框架之Hibernate框架 持续更新中...

    (一)发展历史 在Struts框架中使用jdbc连接来读写数据库,我们最常见的就是打开数据库连接.使用复杂的sql语句进行读写.关闭连接,获得的数据又需要转换或封装后往外传,这是一个非常繁琐的过程. ...

随机推荐

  1. 虚拟化--IO虚拟化基本原理

    本文话题: IO虚拟化概述 设备发现 访问截获 设备模拟 设备共享基于软件的IO虚拟化 基于前端后端的IO虚拟化基于硬件的IO虚拟化 概述 从处理器的角度看,外设是通过一组I/O资源(端口I/O或者是 ...

  2. 使用dreamweaver去掉文本中的空格和换行

    当我们从其他地方拷贝文本到网页,在html代码中会自动带有空格和换行,手动去掉很麻烦,今天试着用dreamweaver去了一下,方法如下: 1.点击Ctrl+F,打开“查找和替换”窗口 2‘见下图:

  3. css利用padding生成图标

    先插入HTML结构: <div class="line-three"></div> <div class="circle"> ...

  4. [原创]VM虚拟机Centos6.4网络配置。

    关于虚拟机VMware 3种网络模式(桥接.nat.Host-only)的工作原理http://www.cnblogs.com/hehexiaoxia/p/4042583.html 操作环境 主机:W ...

  5. Traveling in Blade & Soul

    Traveling in Blade & Soul Walking is too simple. Having trained their physics and spirits for ye ...

  6. express

    1.基于node.js的web开发框架. 2.express目录结构: node_modules public routes views app.js:项目主文件 package.json 3.获取程 ...

  7. C#.NET微信公众账号接口开发系列文章整理--微信接口开发目录,方便需要的博友查询

    前言: 涉及微信接口开发比较早也做的挺多的,有时间的时候整理了开发过程中一些思路案例,供刚学习微信开发的朋友参考.其实微信接口开发还是比较简单的,但是由于调试比较麻烦,加上微信偶尔也会给开发者挖坑,并 ...

  8. 完美解决google无法访问

    1.进入短信界面 2.菜单-设置 3.修改短信中心号码(Set the SIM's smsc number) 保存 [测试结果]:提示保存成功,但是号码没有改变,退出重新进入设置才会看到号码更新 [预 ...

  9. 总结四条对学习Linux系统有帮助的方法

    网络是一个很神奇的东西,现代人的生活离不开网络,网络已深入人们的工作,生活,娱乐等方方面面.网络之所以无处不在,是因为它提供了诸多的网络服务,所以网络服务是网络的灵魂. 互联网上的各种网络服务是架构在 ...

  10. Codeforces Round #370 (Div. 2) E. Memory and Casinos (数学&&概率&&线段树)

    题目链接: http://codeforces.com/contest/712/problem/E 题目大意: 一条直线上有n格,在第i格有pi的可能性向右走一格,1-pi的可能性向左走一格,有2中操 ...