《java_spring_day01-》由会员分享,可在线阅读,更多相关《java_spring_day01-(48页珍藏版)》请在金锄头文库上搜索。
1、达内 IT 培训集团1 知识点列表编号名称描述级别1 Spring的作用及其好处了解 Spring框架的作用* 2 Spring容器实例化掌握 2 中实例化的方式* 3 Spring容器对 Bean 组件的管理通过案例掌握管理Bean 组件的方式, 理解常用属性。* 4 DI 依赖注入理解依赖注入的概念,掌握两种注入方式,了解集合的注入。* 5 组件自动扫描功能注解的使用较流行,理解并掌握常用的几种。* 注:* 理解级别* 掌握级别*应用级别达内 IT 培训集团2 目录1. Spring的作用及优势* . 3 【案例 1】Spring HelloWorld * . 3 2. Spring使用基
2、础* . 12 2.1. Spring容器实例化* . 12 【案例 2】Spring容器实例化* . 12 2.2. Spring容器对 Bean 组件的管理* . 13 【案例 3】Spring容器对 Bean 的管理* . 14 2.3. DI 依赖注入* . 24 【案例 4】DI 依赖注入* . 24 3. 注解方式配置* . 35 3.1. 组件自动扫描功能* . 35 【案例 5】注解方式配置*. 36 达内 IT 培训集团3 1.Spring的作用及优势* Spring用于整合,好处是解耦。解耦,可以降低组件与组件之间的关联,改善程序结构,便于系统的维护和扩展。我们在使用Spr
3、ing框架时,主要是使用Spring容器的两个特性:IoC 和 AoP 。IoC 全称 Inverse of Control(反向控制或控制反转)。在类和类之间存在控制权,控制权指的是对象的创建和使用,比如有类 A 和类 B,我们之前的做法是在A 中调用 B,那么控制权就在A 中,这样做的耦合度较高,如果修改了B,A 也要做相应修改。引入 Spring框架后,控制权由spring容器来负责。当A 想使用 B 时,需要由Spirng容器通过配置文件进行注入。这种思想就是IoC (为了更好的理解,我们可以这样认为,对象创建和使用的控制权转移到了Spring容器,由 Spring容器来控制)。AOP
4、 为 Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的前提下给程序动态统一添加功能的一种技术。Struts2中的拦截器,就是使用AOP 的思想。使用AOP 思想编写程序,会是程序更加灵活。一般而言,使用Spring框架的主要作用:我们会使用IoC 整合组件(各种Bean ),使用 AOP 来管理事务。和 Hibernate相同, Spring的使用也没有限制,到底是用于Web 工程还是普通Java 程序。【案例 1】Spring HelloWorld * 1)新建工程 Spring1 在之前
5、我们的程序开发中,在还没有学习“解耦”思想之前,调用一个组件的过程,我们都这样写:2)调用组件(最初的方式)a.HelloBean 达内 IT 培训集团4 b.UseBean c.Test d.运行 Test 实现了调用组建的功能达内 IT 培训集团5 但是当用户需求发生改变,比如要求输出英文。我们怎么改?修改全部源代码吗?不好。有些问题在开发之初就要预见到,我们需要更良好的程序结构和思想。3)调用组件(更好的方式,工厂模式)a.新建 HelloBean 父类接口b.新建 EnHelloBean c.新建 ZhHelloBean 达内 IT 培训集团6 d.新建 HelloFatory e.修
6、改 UseBean f.运行 Test 进行测试(略)以后只需要在HelloFactory中修改需要创建的组件(HelloBean子类对象)即可。如此这般,就降低了UseBean 和 EnHelloBean(或 ZhHelloBean)之间的耦合度。达内 IT 培训集团7 而当我们使用Spring框架 后,不需要自己写工厂,也可以实现解耦合功能。工厂功能由Spring来实现。Spring的框架及 API 帮助文档,请自行下载或到项目经理处拷贝。文档使用 Spring版本为 spring-framework-2.5.6.SEC014)调用组件(方式3,使用 Spring框架)a.拷贝核心 Jar
7、 包到项目下(共2 个)spring.jar是核心的 Jar 包;该 Jar 包还需要记录日志的commons-logging.jar包请下载 spring_core.zip b.新建 Spring配置文件 applicationContext.xml 固定的写法达内 IT 培训集团8 c.applicationContext.xml 将各种组件( Bean )纳入到 Spring的管理中 d.拷贝文件到tarena.demo2目录下达内 IT 培训集团9 e.修改 UseBean 将需要调用的组件HelloBean声明为自己的属性。注意: 此处不需要new 实例化对象package tare
8、na.demo2; publicclass UseBean private HelloBean hello ; publicvoid show() System.out.println(显示 Hello 消息 ); hello .sayHello(); publicvoid setHello(HelloBean hello) this .hello = hello; 实例化对象在配置文件中进行配置,由spring框架完成达内 IT 培训集团10 f.修改 applicationContext.xml 在配置文件中,通过标签的配置,将enhellobean通过 属性注入 的方式注入到 usebe
9、an中g.修改测试文件Test 使用 Spring框架package tarena.demo2; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import tarena.demo2.UseBean; publicclass Test /* paramargs*/publicstaticvoid main(String args) 达内 IT 培训集团11 ApplicationCo
10、ntext ac = new ClassPathXmlApplicationContext(applicationContext.xml); UseBean bean = (UseBean)ac.getBean(usebean); bean.show(); applicationContext.xml可以放到任意位置,比如这样写h.运行 Test 控制台打印采用 Spring配置的方式,将来只需要修改配置文件即可,如此就实现了“解耦”。(案例结束)达内 IT 培训集团12 2.Spring使用基础* 2.1. Spring容器实例化* 1)BeanFactory XMLBeanFactory-
11、Resource-ClassPathResourceFileSystemResource 2)ApplicationContext(推荐 )ClassPathXmlApplicationContext FileSystemXmlApplicationContext 【案例 2】Spring容器实例化* 1)使用工程 spring1 在 Spring当中有两个重要的对象。容器在实例化时,我们可以使用2 种方式加载Spring配置文件,创建Spring容器:其中 ApplicationContext是 BeanFactory的子类,在我们实例化对象时,如下两种方式的效果是等价的。在一些文档中推荐使
12、用ApplicationContext,功能更强大。推荐使用方式1 ApplicationContext还有一些子类,可实现不同功能:达内 IT 培训集团13 假设我们的配置文件直接存放在硬盘某个位置,我们可以使用FileSystemXmlApplicationContext 来找到配置文件(案例结束)2.2. Spring容器对 Bean 组件的管理* 1)Bean 对象创建的时机默认 是随着容器创建,可以使用lazy-init=true(在调用 getBean创建)延迟创建也可以用 批量延迟创建2)Bean 对象的创建模式默认 是单例,可以使用scope 属性改变。singleton:单例
13、,每次调用getBean返回同一个prototype:原型,每次调用getBean返回一个新的request: 仅限于 Web 环境session: 仅限于 Web 环境global session:仅限于 Web 环境3)Bean 对象初始化和 销毁init-method属性用于指定初始化方法destroy-method属性用于指定销毁方法,仅适用于singleton模式达内 IT 培训集团14 【案例 3】Spring容器对 Bean 的管理* 1)使用 spring1工程2)新建 tarena.demo3 提问: Bean 对象是什么时候创建的?让我们测试一下3)新建组件 tarena.
14、demo3.MyBean 为 MyBean添加构造器package tarena.demo3; publicclass MyBean public MyBean() System.out.println(创建 MyBean 对象 ); 4)applicationContext.xml中进行配置将 MyBean纳入 spring的管理5)创建 Spring容器实例达内 IT 培训集团15 此时,我们只通过加载配置文件创建Spring容器实例package tarena.demo3; import org.springframework.context.ApplicationContext; im
15、port org.springframework.context.support.ClassPathXmlApplicationContext; publicclass Test privatestaticfinal String CONFIGS = tarena/demo3/applicationContext.xml; /* paramargs*/publicstaticvoid main(String args) ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIGS); 6)运行 Test MyBean组件是
16、什么时间创建的?控制台打印结果显示,默认 情况下 MyBean在 Spring容器被创建时就会被创建。如果我们想 改变对象创建的时机,该怎么做?通过修改配置文件属性参数,可以改变Spring容器创建对象的时机。7)修改 applicationContext.xml 8)运行 Test 控制台什么都没有打印,对象实例化被延迟了。设置了 之后, MyBean是什么时候被创建的?当调用(使用) MyBean时, MyBean对象被创建,如下所示9)修改 Test 代码片段privatestaticfinal String CONFIGS = tarena/demo3/applicationConte
17、xt.xml; /*达内 IT 培训集团17 * paramargs*/publicstaticvoid main(String args) ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIGS); MyBean bean = (MyBean)ac.getBean(mybean); 10)运行 Test 当调用 /使用 MyBean对象时,才被创建我们还可以这样配置,让所有的 bean 都延迟创建 。11)修改 applicationContext.xml 这样可以批量指定延迟加载bean 再提一个问题:bean
18、对象的 创建模式 是什么,是单例模式创建Bean 对象还是每次创建都是新的?让我们进行测试12)修改 Test 创建 2 个 MyBean对象,通过对比,如果为 true ,则表明是单例模式;如果为false ,则表明每次都创建新的MyBean对象package tarena.demo3; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; publicclass Test private
19、staticfinal String CONFIGS = tarena/demo3/applicationContext.xml; /* paramargs*/publicstaticvoid main(String args) ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIGS); MyBean bean1 = (MyBean)ac.getBean(mybean); MyBean bean2 = (MyBean)ac.getBean(mybean); System.out.println(bean1=bean2
20、); 13)运行 Test 通过运行结果,我们可以看得出,Spring容器是通过 单例模式 创建 Bean 对象的,也就是说,默认 情况下,通过调用ac.getBean(mybean)方法获得的对象都是同一个mybean对象达内 IT 培训集团19 使用单例模式有风险,风险在于多线程并发访问时会有一些状况。那么 如何取消容器默认单例模式创建对象?14)修改 applicationContext.xml 设置创建 bean 的模式为 原型模式( prototype)即可以代码片段15)运行 Test 注意: 调用了 2 次 MyBean的构造方法,说明创建了2 个对象达内 IT 培训集团20 s
21、cope 属性的取值在 web (仅限于 web 项目)环境中,还可以设置所创建的bean 对象的生命周期和request 、session request 表示 bean 对象生命周期和request生命周期相同session 同 session global session 相当于 application single prototype Bean 对象的初始化和销毁init-method属性 用于指定初始化方法destroy-method属性 用于指定销毁方法,仅适用于singleton模式16)修改 MyBean 加入方法 myinit( ) 方法 mydestory( ) packa
22、ge tarena.demo3; publicclass MyBean public MyBean() System.out.println(创建 MyBean 对象 ); publicvoid myinit() System.out.println(执行 MyBean 对象的初始化! ); publicvoid mydestroy() System.out.println(执行 MyBean 对象的销毁!释放资源!); 17)修改 applicationContext.xml 希望在 bean 对象创建后自动调用myinit() 方法代码片段18)修改 Test publicclass Te
23、st privatestaticfinal String CONFIGS = tarena/demo3/applicationContext.xml; /* paramargs*/publicstaticvoid main(String args) ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIGS); MyBean bean = (MyBean)ac.getBean(mybean); 19)执行 Test 自定义的初始化的方法在对象被创建后调用20)修改 applicationContext.xml 希望在 b
24、ean 对象销毁前自动调用mydestory()方法代码片段如果想看演示结果,我们需要知道bean 对象在什么时候被销毁的。那么 bean 对象在什么时候被销毁呢?bean 对象在 spring容器关闭的时候被销毁。为了看到结果,我们需要做一些修改21)修改 Test publicclass Test privatestaticfinal String CONFIGS = tarena/demo3/applicationContext.xml; /* paramargs*/publicstaticvoid main(String args) AbstractApplicationContext
25、 ac = new ClassPathXmlApplicationContext(CONFIGS); MyBean bean = (MyBean)ac.getBean(mybean); ac.close(); 22)运行 Test 达内 IT 培训集团23 我们发现没有打印预期的执行了destory()方法的结果。原因是因为在applicationContext.xml文件中设置的destory-method=属性仅仅对单例模式起作用,在prototype模式下没有意义。23)修改 applicationContext.xml 24)运行 Test 达内 IT 培训集团24 (案例结束)2.3
26、. DI 依赖注入* DI(依赖注入)是IoC 实现的重要技术,有如下2 中方式:1)setter方式注入2)构造方式注入注入类型有如下几种:简单值、集合、bean 对象Ioc 和 DI 的关系?我们认为 Spring是具有 IoC 特性的框架。实现 IoC 是由 Spring容器来完成的,Spring容器通过依赖注入DI 建立起对象(组件、Bean )之间的关系。我们可以这样理解:DI 是 IoC 实现的一种手段,Ioc 通过 DI 来实现。【案例 4】DI 依赖注入* 像这样的 bean 组件是怎么注入的?达内 IT 培训集团25 引入 Spring中一个重要概念DI(依赖注入)DI(依赖
27、注入)有2 种方式:1)setter方式注入我们在之前的案例中使用的方式(推荐使用)2)构造方式注入演示如下1)使用 spring1工程2)新建 tarena.demo4 我们想在 bean 对象 A 中使用 bean 对象 B 如果这样写,好吗?不好。这样写和不使用Spring框架没区别。类A 和类 B 之间的耦合度太高。所以,我们要这样写方式 1:set 方法注入3)新建 IB 达内 IT 培训集团26 4)新建 B 5)新建 A 6)修改 applicationContext.xml 达内 IT 培训集团27 7)新建 Test 如上是 set 方式注入,接下里演示构造方式注入8)修改
28、A 添加构造器,不需要属性的set 方法达内 IT 培训集团28 9)修改 applicationContext.xml 10)运行 Test 达内 IT 培训集团29 如果想 注入多个值 怎么做?使用构造方式注入多个值11)修改 A 12)修改 applicationContext.xml 13)运行 Test 达内 IT 培训集团30 Set 方式注入多个值14)修改 A 15)修改 applicationContext.xml 达内 IT 培训集团31 那么到底该如何选择使用set 方式注入还是构造方式注入?如果需要注入的值非常多,那么使用构造方式就不太合适,在开发过程中,set 方式使
29、用的也较多些。如果 bean 属性中有 集合 ,那么如何配置使用?16)新建 CollecitonBean package tarena.demo4; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; publicclass CollectionBean private List city ; private Set name ; private Map books ; private Properties params ; publicvoid set
30、Params(Properties params) this .params = params; publicvoid setBooks(Map books) this .books = books; publicvoid setName(Set name) this .name = name; publicvoid setCity(List city) this .city = city; 达内 IT 培训集团32 publicvoid show() System.out.println(#List 城市信息 # ); for (String s: city ) System.out.pri
31、ntln(s); System.out.println(#Set 朋友信息 # ); for (String s: name ) System.out.println(s); System.out.println(#Map图书信息 # ); Set keys = books .keySet(); for (String key:keys) System.out.println(key+ : + books .get(key); System.out.println(#Properties数据库连接参数信息# ); Set ids = params .keySet(); for (Object
32、id:ids) System.out.println( id+ : + params .getProperty(id.toString(); 17)applicationContext.xml 北京 上海 深圳 tom jack rose root root com.mysql.jdbc.Driver jdbc:mysql:/localhost:3306/test达内 IT 培训集团34 18)Test package tarena.demo4; import org.springframework.context.ApplicationContext; import org.springfr
33、amework.context.support.ClassPathXmlApplicationContext; publicclass Test privatestaticfinal String CONFIGS = tarena/demo4/applicationContext.xml; publicstaticvoid main(String args) ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIGS); CollectionBean bean = (CollectionBean)ac.getBean(c
34、ollectionbean); bean.show(); 19)运行 Test 达内 IT 培训集团35 (案例结束)3.注解方式配置* 常用配置方式有XML 文档配置 ,还有一种是通过注解方式配置。采用注解方式的 目的 就是为了简化XML 配置文件。注解方式(也叫注释)是JDK5 版本提供的,之前的版本不支持。Spring2.5版本后支持注解方式,之前的版本不支持。3.1. 组件自动扫描功能* 首先需要在applicationContext.xml中添加 1)扫描 Bean 组件的注解,替代xml 中的 元素的定义。Service 用于 Service 业务组件Control 用于 Acti
35、on控制组件Respository 用于 DAO 数据访问组件达内 IT 培训集团36 Component 用于其他组件Bean 组件扫描到容器后,默认名字为类名(首字母小写 )如果需要自定义名称可以使用Service(id名) 2)依赖注入的注解标记Resource 按名称 Resource(name=id名) AutoWired 按名称Autowired Qualifier(id名) 3)其他注解Scope 等价于 PostConstruct 等价于 PreDestroy 等价于 【案例 5】注解方式配置* 我们不采用xml 的方式注入属性了,采用注解的方式注入1)使用工程 spring1
36、 2)采用注解的方式a.修改 applicationContext.xml Xml 文档中不再配置bean 了,我们引入新的标签标签的作用是进行组件自动扫描注意, 使用此标签的前提是必须具有xmlns:context命名空间注意, 和之前的 applicationContext.xml做对比,有些命名空间现在用不到就可以删除。达内 IT 培训集团37 b.HelloBean package tarena.demo5; publicinterface HelloBean publicabstractvoid sayHello(); c.修改 ZhHelloBean 注意: 容器如何找到ZhHel
37、loBean的?如果只写 Service ,默认 情况下相当于在applicationContext.xml中这样配置 默认 情况下,容器将类名ZhHelloBean首字母小写,作为的 id package tarena.demo5; import org.springframework.stereotype.Service; Service publicclass ZhHelloBean implements HelloBean publicvoid sayHello() System.out.println(世界你好! ); d.修改 Test package tarena.demo5;
38、import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; publicclass Test privatestaticfinal String CONFIG = tarena/demo5/applicationContext.xml; publicstaticvoid main(String args) ApplicationContext ac = 达内 IT 培训集团38 new Class
39、PathXmlApplicationContext(CONFIG); ZhHelloBean hello = (ZhHelloBean)ac.getBean(zhHelloBean); hello.sayHello(); e.运行 Test 3)采用 xml配置的方式 (之前的方式)a.修改 applicationContext.xml 使用 xml 配置这里 的 id 可以自定义为任意的字符,比如此处都为小写b.修改 ZhHelloBean 木有注解package tarena.demo5; 达内 IT 培训集团39 publicclass ZhHelloBean implements He
40、lloBean publicvoid sayHello() System.out.println(世界你好! ); c.Test publicclass Test privatestaticfinal String CONFIG = tarena/demo5/applicationContext.xml; publicstaticvoid main(String args) ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIG); ZhHelloBean hello = (ZhHelloBean)ac.getBean
41、(zhhellobean); hello.sayHello(); d.运行 Test 通过对比,我们发现注解的方式更简便些。当然,我们可以自定义注解需要使用bean 的名字4)修改 ZhHelloBean 达内 IT 培训集团40 5)修改 Test 如果我们使用UseBean调用 HelloBean ,使用注解方式该怎么做?使用配置文件的方式,我们这样做使用注解方式,我们这样做达内 IT 培训集团41 6)UseBean 在属性上加入 Resource注解,相当于 package tarena.demo5; import javax.annotation.Resource; / 该注解是由
42、JDK提供,而非 Spring 提供的import org.springframework.stereotype.Service; Service (usebean) publicclass UseBean Resourceprivate HelloBean hello ; publicvoid show() System.out.println(显示 Hello 消息 ); hello .sayHello(); publicvoid setHello(HelloBean hello) this .hello = hello; 7)ZhHelloBean package tarena.demo
43、5; import org.springframework.stereotype.Service; Service (zhhellobean) publicclass ZhHelloBean implements HelloBean publicvoid sayHello() System.out.println(世界你好! ); 达内 IT 培训集团42 8)Test package tarena.demo5; import org.springframework.context.ApplicationContext; import org.springframework.context.s
44、upport.ClassPathXmlApplicationContext; publicclass Test privatestaticfinal String CONFIG = tarena/demo5/applicationContext.xml; publicstaticvoid main(String args) ApplicationContext ac = new ClassPathXmlApplicationContext(CONFIG); UseBean bean = (UseBean)ac.getBean(usebean); bean.show(); 9)运行 Test 总
45、结:Service (zhhellobean)相当于 xml 文件中配置 达内 IT 培训集团43 Resource 相当于 xml 文件中配置 其他的注解的使用首先需要在applicationContext.xml中添加 1.扫描 Bean 组件的注解,替代xml 中的 元素的定义。Service 用于 Service业务组件Control 用于 Action控制组件Respository 用于 DAO 数据访问组件Component 用于其他组件Bean 组件扫描到容器后,默认名字为类名(首字母小写 )如果需要自定义名称可以使用Service(id名) 2.依赖注入的注解标记Resourc
46、e JDK 提供的先按类型,后按名称来自动装配AutoWired Spring提供的先按名称,后按类型来自动装配Qualifier(id名) 3.其他注解Scope 等价于 PostConstruct 等价于 PreDestroy 等价于 和Resource 的功能相同, Autowired也是用于自动装配的。达内 IT 培训集团44 10)修改 UseBean 我们使用 Autowired结果是一样的。注意: 不论使用 Resource还是 Autowried,我们 不用再写 set 方法 的。我们这样写的时候,表示只有注解名字相同时,才自动装配。11)修改 UseBean 在之前,我们都只
47、装配zhhellobean,现在我们想将enhellobean也装配进来12)ZhHelloBean 达内 IT 培训集团45 13)修改 EnHelloBean 此时,如果我们这样写,就会出异常14)UseBean 达内 IT 培训集团46 15)运行 Test 出现异常异常显示如下,表示有两个符合条件的bean ,spring不知该选哪个了Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type tarena.demo5.HelloBean is de
48、fined: expected single matching bean but found 2: enhellobean, zhhellobean这种情况下,只能通过Resource(name=)来指定。当然,一般情况下,还是推荐 直接使用简单的 Resource Resource 按照名字注入的方法较简单,Autowired按照名字注入需要再加一个注解16)修改 UseBean 达内 IT 培训集团47 这些也有配套的注解scope 等价于 scope 属性PostConstruct等价于 init-method PreDestroy等价于 destory-method 如下所示17)修改 UseBean 注解形式和xml 形式各有优劣,注解方式现在比较流行。注解方式的优点是使用方便,缺点是和Java 代码掺和在一起,不好修改。Xml 方式的优点是修改方便,但是缺点是配置工作量较大。(案例结束)达内 IT 培训集团48