JavaWeb Spring开发入门深入学习

1 Spring基本特征

Spring是一个非常活跃的开源框架;它是一个基于Core来构架多层JavaEE系统的框架,它的主要目地是简化企业开发.
Spring以一种非侵入式的方式来管理你的代码,Spring提倡”最少侵入”,这也就意味着你可以适当的时候安装或卸载Spring,Spring让java亮了。 (开放–闭合原理),这里是闭原则。

2 开发spring所需要的工具

(这里先将spring2.5 ,后面3.0)

2.1 Spring的jar包

到http://www.springsource.org/download下载spring,然后进行解压缩,在解压目录中找到下面jar文件,拷贝到类路径下

—spring的核心类库 在spring文档的dist下 dist\spring.jar

—引入的第三方类库 都spring文档的lib下,lib\jakarta-commons\commons-logging.jar

—如果使用了切面编程(AOP),还需要下列jar文件 lib/aspectj/aspectjweaver.jar和aspectjrt.jarlib/cglib/cglib-nodep-2.1_3.jar

—如果使用了JSR-250中的注解,如@Resource/@PostConstruct/@PreDestroy,还需要下列jar文件lib\j2ee\common-annotations.jar

注:JSR(Java 规范请求)是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR(Java 规范请求),以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准

2.2 Spring配置文件

默认情况下是applicationContext.xml文件。可以建立很多xml文件,工程中一般都是这样配置的。(src目录下建)

3 Spring基本功能详解

3.1 SpringIOC

Spring的控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。

步骤:
 •A. 启动spring容器
1、 在类路径下寻找配置文件来实例化容器

代码如下:

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});

可以在整个类路径中寻找xml文件
* 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下
* classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。

2、 在文件系统路径下寻找配置文件来实例化容器

Spring的配置文件可以指定多个,可以通过String数组传入。
注:经常用第一种方法启动容器
 •B. 从spring容器中提取对象

spring 容器结构:

3.2 别名

<beans>
 <alias name="person" alias="p"/>//alias这里是别名,可以通过p,得到person这个bean.
 <bean name="person" class="cn.itcast.aliasspring.Person"/>
</beans>

通过这样的配置,可以达到在一个地方命名,在多个地方使用不同的名字的效果。

3.3 Spring容器内部对象

1 创建对象的方式

1.1 无参构造函数

<bean id="helloWorld" class="com.itheima10.spring.createobject.HelloWorld"></bean>

1.2 静态工厂方法

<bean id="helloWorld2" class="com.itheima10.spring.createobject.method.HelloWorldFactory"
factory-method="getInstance"></bean>

1.3 实例工厂方法

<bean id="helloWorldFactory" class="com.itheima10.spring.createobject.method.HelloWorldFactory2"></bean>
<bean id="helloWorld3" factory-bean="helloWorldFactory" factory-method="getInstance"></bean>

记住概念即可,用的最多的是第一种方法,但是和别的工具集成时,用的是实例工厂模式。

实例
配置applicationContext.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-2.5.xsd">
 <!--
 把一个类放入到spring容器中,该类就称为一个bean
 -->
 <!--
 bean描述了一个类
  id 唯一的标示
  class 类的全名
 -->

 <bean id="helloWorld" class="com.itheima10.spring.createobject.HelloWorld"></bean>

 <!-----------------------别名-------------------------------------->
 <!--
 name的属性和bean的id匹配
 alias 别名
 -->
 <alias name="helloWorld" alias="狗蛋"/>
 <alias name="helloWorld" alias="习近平"/>
<!-----------------------静态工厂方法-------------------------------------->
<!--
 把helloWorldFactory放入到spring容器中
 factory-method 工厂方法
 -->
 <bean id="helloWorld2"
 factory-method="getInstance"
 class="com.itheima10.spring.createobject.method.HelloWorldFactory"></bean>
<!-----------------------实例工厂方法-------------------------------------->
 <!--
 把helloWorldFactory2放入到spring容器中
 factory-bean 指明了工厂bean
 factory-method 指明了该工厂bean中的方法
 -->
 <bean id="helloWorldFactory" class="com.itheima10.spring.createobject.method.HelloWorldFactory2"></bean>
 <bean id="helloWorld3"
 factory-bean="helloWorldFactory"
 factory-method="getInstance"></bean>
</beans>

建立实体类HelloWorld

package com.itheima10.spring.createobject;

public class HelloWorld {
 public void hello(){
 System.out.println("hello");
 }
}

建立静态工厂HelloWorldFactory

package com.itheima10.spring.createobject.method;

public class HelloWorldFactory {
 public static HelloWorld getInstance(){
 System.out.println("static method");
 return new HelloWorld();
 }
}

建立实体工厂HelloWorldFactory2

package com.itheima10.spring.createobject.method;

public class HelloWorldFactory2 {
 /**
 * 必须先创建工厂对象,才能调用该方法
 * @return
 */
 public HelloWorld getInstance(){
 return new HelloWorld();
 }
}

编写测试方法CreateObjectMethodTest

package com.itheima10.spring.createobject.method;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 第二种和第三种产生方式能看明白就OK了
 * @author zd
 *
 */
public class CreateObjectMethodTest {
 /**
 * 在默认情况下,spring容器调用的是一个类的默认的构造函数创建对象
 */
 @Test
 public void testCreateObject_Default(){
 ApplicationContext context =
  new ClassPathXmlApplicationContext("applicationContext.xml");
 HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
 helloWorld.hello();
 }

 /**
 * 利用静态工厂创建对象
 * <bean id="helloWorld2"
 factory-method="getInstance"
 class="com.itheima10.spring.createobject.method.HelloWorldFactory"></bean>
  spring容器做的事情:
  利用HelloWorldFactory类调用了getInstance方法
 */
 @Test
 public void testCreateObject_StaticFactory(){
 ApplicationContext context =
  new ClassPathXmlApplicationContext("applicationContext.xml");
 HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld2");
 helloWorld.hello();
 }

 /**
 * 实例工厂方法创建对象
 * <bean id="helloWorldFactory"
 * class="com.itheima10.spring.createobject.method.HelloWorldFactory2"></bean>
 * <bean id="helloWorld3"
 factory-bean="helloWorldFactory"
 factory-method="getInstance"></bean>
 spring容器内部做的事情:
  1、创建一个helloWorldFactory对象
  2、由该对象调用getInstance产生helloWorld对象
 */
 @Test
 public void testCreateObject_InstanceFactory(){
 ApplicationContext context =
  new ClassPathXmlApplicationContext("applicationContext.xml");
 HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld3");
 helloWorld.hello();
 }
}

2 对象的scope

对象的scope有两个属性:singleton 与prototype。singleton表示单例
2.1 singleton(默认值)

在每个Spring IoC容器中一个bean定义只有一个对象实例(共享)。

2.2 prototype
允许bean可以被多次实例化(使用一次就创建一个实例) . Spring不能对一个prototype bean的整个生命周期负责.这就意味着清楚prototype作用域的对象并释放任何prototype bean所持有的昂贵资源都是客户端的责任。

<bean id="helloWorld" class="com.itheima10.spring.scope.HelloWorld" scope="singleton"></bean>
<bean id="helloWorld" class="com.itheima10.spring.scope.HelloWorld" scope="prototype"></bean>

建立HelloWorld类

public class HelloWorld {
 public List<String> lists = new ArrayList<String>();
 public HelloWorld(){
 System.out.println("new instance");
 }
 public void hello(){
 System.out.println("hello");
 }
}

建立测试类ScopeTest

package com.itheima10.spring.scope;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ScopeTest {
 /**
 * 把一个bean放入到spring容器中,默认的是单例
 * 如果一个类放入到spring容易中,而这个类是单例的,那么该类中的属性将会成为共享的
 */
 @Test
 public void testCreateObject_Scope_Default(){
 ApplicationContext context =
  new ClassPathXmlApplicationContext("applicationContext.xml");
 HelloWorld hello1 = (HelloWorld)context.getBean("helloWorld");
 hello1.lists.add("aaaa");
 hello2= (HelloWorld)context.getBean("helloWorld");
 hello2.lists.add("bbbb");
 System.out.println(helloWorld.lists.size());//2,并且只输出一次new instance
 }

 /**
 * 如果spring的配置文件如下:
 * <bean id="helloWorld"
 class="com.itheima10.spring.scope.HelloWorld"
 scope="prototype"></bean>
 那么spring容器会为创建多个对象
 */
 @Test
 public void testCreateObject_Scope_Prototype(){
 ApplicationContext context =
  new ClassPathXmlApplicationContext("applicationContext.xml");
 HelloWorld hello1 = (HelloWorld)context.getBean("helloWorld");
 hello1.lists.add("aaaa");
 hello2= (HelloWorld)context.getBean("helloWorld");
 hello2.lists.add("bbbb");
 System.out.println(helloWorld.lists.size());//1,并且只输出两次new instance
 }
}

3 初始化bean时机

懒加载——默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:

<bean id="xxx" class="cn.itcast.OrderServiceBean" lazy-init="true"/>

如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:

<beans default-lazy-init="true“ ...>

Spring默认在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化的一部分,ApplicationContext会自动创建并配置所有的singleton bean.通常情况下这是件好事。因为这样在配置中有任何错误能立即发现。

Lazy-init 为false,spring容器将在启动的时候报错(比较好的一种方式)
Lazy-init 为true,spring容器将在调用该类的时候出错。

配置applicationContext.xml

<bean id="helloWorld"
 class="com.itheima10.spring.createobject.when.HelloWorld"
 scope="prototype"></bean>
</beans>

建立测试类CreateObjectWhenTest

package com.itheima10.spring.createobject.when;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CreateObjectWhenTest {
 /**
 * 默认情况下的顺序
 * 1、启动spring容器
 * 2、创建HelloWorld对象
 * 3、对象调用方法
 *
 * <bean id="helloWorld" class="com.itheima10.spring.createobject.when.HelloWorld"></bean>
  <bean id="helloWorld2" class="com.itheima10.spring.createobject.when.HelloWorld"></bean>
  因为在spring容器中声明了两个bean,所以spring容器要创建两个对象
  说明:
  如果struts2,hibernate,spring容器整合,如果spring的配置文件中出现错误
  当 tomcat容器启动的时候,就会报错,错误会特别早的显示出来

  如果一个bean存放了大量的数据,这种方式不好,有可能会把数据过早的停留在内存中

  如果一个bean不是单例,那么不管怎么样配置,都在是context.getBean时才要创建对象
 */
 @Test
 public void testCreateObject_When_Default(){
 ApplicationContext context =
   new ClassPathXmlApplicationContext("applicationContext.xml");
 context.getBean("helloWorld");
 }

 /**
 * <bean id="helloWorld"
 class="com.itheima10.spring.createobject.when.HelloWorld"
 lazy-init="true"></bean>
 * 顺序
 * 1、启动spring容器
 * 2、context.getBean
 * 3、调用构造器函数创建对象
 * 说明:
  如果struts2,hibernate,spring容器整合,如果spring的配置文件中出现错误
  只有当用到该bean的时候才会报错。

  如果一个bean存放了大量的数据,需要的时候才要加载数据
 */
 @Test
 public void testCreateObject_When_Lazy(){
 ApplicationContext context =
   new ClassPathXmlApplicationContext("applicationContext.xml");
 context.getBean("helloWorld");
 }
}

4 init、destroy方法

Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。可以指定方法进行操作。

<bean id=“foo” class=“...Foo” init-method=“setup” destory-method=“teardown”/>

当foo被载入到Spring容器中时调用init-method方法。当foo从容器中删除时调用destory-method(scope = singleton有效)

编写HelloWorld

public class HelloWorld {
 public HelloWorld(){
 System.out.println("new instance");
 }

 public void init(){
 System.out.println("init");
 }

 public void destroy(){
 System.out.println("destroy");
 }

 public void hello(){
 System.out.println("hello");
 }
}

编写测试类InitDestroyTest

package com.itheima10.spring.ioc.initdestroy;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class InitDestroyTest {
 /**
 * init-method="init"
 * 执行顺序:
 * 1、启动spring容器
 * 2、创建helloWorld对象
 * 3、执行init方法
 *  spring容器内部自动执行的
 * 4、对象调用方法
 * 5、只有当spring容器关闭掉的情况下才能执行destroy方法 前提条件:bean是单例的
 *  该方法也是由spring容器内部调用的
 * 说明:
 * 如果一个bean不是单例的,则spring容器不负责对象的销毁。
 * 在spring容器中,只有一个bean是单例的情况下,spring容器才要负责对象的创建、初始化、销毁工作
 * 如果一个bean不是单例,spring容器只负责创建、初始化
 */
 @Test
 public void testInitDestroy(){
 ApplicationContext context =
  new ClassPathXmlApplicationContext("applicationContext.xml");
 HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
 helloWorld.hello();
 ClassPathXmlApplicationContext applicationContext = (ClassPathXmlApplicationContext)context;
 applicationContext.close();
 }
}

执行顺序图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Java Spring各种依赖注入注解的区别

    注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Component. Autowired是自动注入,自动从spring的上下文找到合适的bean来注入 Resource用来指定名称注入 Qualifier和Autowired配合使用,指定bean的名称 Service,Controller,Repository分别标记类是Service层类,Contro

  • 详解Java的Spring框架中的事务管理方式

    数据库事务是被当作单个工作单元的操作序列.这些操作要么全部完成或全部不成功.事务管理是面向企业应用程序,以确保数据的完整性和一致性RDBMS中的重要组成部分.事务的概念可以用下面的描述为ACID四个关键属性来描述: 原子性: 一个事务应该被视为单个操作单元表示的操作的任一整个序列是成功的或不成功的. 一致性: 这代表了数据库的参照完整性,在桌等唯一主键的一致性 隔离性: 可能有很多事务处理相同的数据集的同时,每个事务都应由他人隔离,以防止数据损坏. 持久性: 一旦事务完成,本次事务的结果必须作出

  • Java Spring Controller 获取请求参数的几种方法详解

    Java Spring Controller 获取请求参数的几种方法  1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交.若"Content-Type"="application/x-www-form-urlencoded",可用post提交 url形式:http://localhost:8080/SSMDemo/demo/addUser1?username=lixiaoxi&password=1

  • 在Java的Spring框架中配置Quartz的教程

    Spring中配置Quartz的过程: 1.导入JAR包 quartz需要的JAR包,已经包含在spring中,位置在spring解压后目录的 \lib\quartz 下的quartz-all-1.6.1.jar, 将其拷贝到工程 的 WEB-INF/lib 下就行了. 2.配置web.xml,让spring启动时加载quartz的配置文件 <?xml version="1.0" encoding="UTF-8"?> <web-app versio

  • 从最基本的Java工程搭建SpringMVC+SpringDataJPA+Hibernate

    本文会介绍从一个最基本的java工程,到Web工程,到集成Spring.SpringMVC.SpringDataJPA+Hibernate. 平时我们可能是通过一个模板搭建一个工程,或者是直接导入一个项目,而本文选择从最基本的java工程开始,目的是为了展示更多原理. 当然,我们还是从一个最基本的Maven工程开始,其实普通的非Maven工程,搭建过程几乎是一模一样的,只是Jar包需要我们手动的添加到工程中,而Maven工程就只是修改配置文件即可. 下面就正式开始. 1.基于Maven(如果不使

  • Java Spring MVC 上传下载文件配置及controller方法详解

    下载: 1.在spring-mvc中配置(用于100M以下的文件下载) <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <!--配置下载返回类型--> <bean class="or

  • Java Spring快速入门

    一.Spring是什么? Spring是一个开源框架, Spring为简化企业级应用开发而生,使用Spring可以使简单的JavaBean实现以前只有EJB才能实现的功能. Spring是一个IOC(DI)和AOP容器框架. 二.具体描述Spring 轻量级:Spring是非侵入式的-基于Spring开发的应用中的对象可以不依赖Spring的API 依赖注入:(DI-Dependency injection.IOC) 面向切面编程:(AOP-aspect oriented programming

  • Java SpringMVC实现PC端网页微信扫码支付(完整版)

    一:前期微信支付扫盲知识 前提条件是已经有申请了微信支付功能的公众号,然后我们需要得到公众号APPID和微信商户号,这个分别在微信公众号和微信支付商家平台上面可以发现.其实在你申请成功支付功能之后,微信会通过邮件把Mail转给你的,有了这些信息之后,我们就可以去微信支付服务支持页面:https://pay.weixin.qq.com/service_provider/index.shtml 打开这个页面,点击右上方的链接[开发文档]会进入到API文档说明页面,看起来如下 选择红色圆圈的扫码支付就

  • Java类获取Spring中bean的5种方式

    获取Spring中的bean有很多种方式,再次总结一下: 第一种:在初始化时保存ApplicationContext对象 ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml"); ac.getBean("beanId"); 说明:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring. 第二种:通过Spring提供

  • Java Spring 事务回滚详解

    spring 事务回滚 1.遇到的问题 当我们一个方法里面有多个数据库保存操作的时候,中间的数据库操作发生的错误.伪代码如下: public method() { Dao1.save(Person1); Dao1.save(Person2); Dao1.save(Person2);//假如这句发生了错误,前面的两个对象会被保存到数据库中 Dao1.save(Person2); } 期待的情况:发生错误之前的所有数据库保存操作都回滚,即不保存 正常情况:前面的数据库操作会被执行,而发生数据库操作错

  • 实例讲解Java的Spring框架中的AOP实现

    简介 面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足. 除了类(classes)以外,AOP提供了 切面.切面对关注点进行模块化,例如横切多个类型和对象的事务管理. (这些关注点术语通常称作 横切(crosscutting) 关注点.) Spring的一个关键的组件就是 AOP框架. 尽管如此,Spring IoC容器并不依赖于AOP,这意味着你可以自由选择是否使用AOP,AOP提供强大的中间件解决方案,这使得Spring IoC容器更加完善

随机推荐