专题一
(1)Spring Framework Runtime
Test模块支持使用JUnit和TestNG对Spring组件进行测试。Core Container(核心容器)包含有Beans、Core、Context和SpEL模块。AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现。Data Access/Integration层包含有JDBC、ORM、OXM、JMS和Transaction模块。Web层包含了Web、Web-Servlet、WebSocket、Web-Porlet模块。
(2)轻量级JavaEE VS 重量级(传统)JavaEE两层含义:
1,轻量级是相对于重量级而言的,轻量级一般就是非入侵性的、所依赖的东西非常少、资源占用非常少、部署简单等等,其实就是比较容易使用,而重量级正好相反。
2,相比较传统的JavaEE项目,即真正意义上的JavaEE规范(比如EJB3.0;JPA;JMX;JMS;JNDI;JSF等),我们把能直接在Tomcat等符合JavaServlet规范的Web服务器上能直接运行的Java应用称为轻量级的JavaEE应用;一般就意味着以Spring为代表的一些事实上的标准开发框架;可以说,Spring就是运行在Web服务器中的ApplicationServer;
(3)Spring的系列产品;Spring Boot:为基于Spring的应用开发提供了基础的项目构建;Spring Data:用于简化数据库访问,并支持云服务的开源框架。旨在统一和简化对各类型持久化存储, 而不拘泥是关系型数据库还是NoSQL数据存储。Spring Batch:专门针对企业级系统中的日常批处理任务的轻量级框架,能够帮助开发者方便地开发出强壮、高效的批处理应用程序。Spring Integration:为Spring编程模型提供了一个支持企业集成模式(Enterprise Integration Patterns)的扩展,在应用程序中提供轻量级的消息机制,可以通过声明式的适配器与外部系统进行集成。Spring Security:早期称为Acegi,基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架;。Spring Roo:快速应用程序开发工具,可以在短时间内方便地构建应用程序。Spring Mobile:对Spring MVC的扩展,旨在简化移动Web应用的开发。Spring for Android:用于简化Android原生应用程序开发的Spring扩展。
(4)Spring的版本
Spring2.5:
¨拥抱驱动编程。
支持SimpleJdbcTemplate的命名参数操作。
Spring3.x:
不再支持JDK1.4;
¨全面支持泛型。
支持SpEL.
支持WebService的OXM。
Spring4.x:
支持Java8,支持JavaEE6规范。
泛型限定式依赖注入。
对Hibernate4的集成和事务提供更好的管理方案。
(5)IOC的概念
IoC:inverseof control,即控制反转;
简单的说,就是把对象的实例化工作交给容器来完成;
遇到的问题:
1,业务代码都使用接口,按照接口编程,能够解除耦合;
2,使用传统的开发方式,虽然在业务声明,业务代表调用上确实使用的是接口,但是这个业务类的实体需要客户端自己去初始化,初始化一定是某一个具体的接口实现类,所以,并没有做到完全的解耦;
A和B两个类,A类使用到B类,A类就要负责B类的实例化过程,
怎么做?A类依赖B类,A类不要直接去实例化B类,而是把实例化B类的过程交给容器,A类只需要从容器中取得初始化的实例化对象;
(6)基于Spring的HelloWorld:
1,基础代码(接口+实现);
2,拷贝core.jar和beans.jar
3,告诉spring要管理的bean--->配置文件(在spring中配置文件一般命名为application.xml或者appliactionContext.xml)
4,测试:
在HelloWorld实例中,注意:
1,从容器中拿对象,使用的是接口拿(这样才能真正做到解耦);
2,研究从Spring中拿Bean的原理:
1,先从classpath下加载Spring的配置文件;
2,使用配置文件创建一个BeanFactory对象;
1,遍历配置文件中所有的bean元素;
2,根据bean元素的class属性去创建一个对象的实例(Class.forName(“class”)).newInstance();
3,把创建好的实例+bean元素中的id存放到容器中;
3,使用getBean方法的时候,就是按照查询(getBean)的方式,从容器中找到合适的bean的实例并返回;
** ****结论:**
1,默认情况下,交给Spring管理的bean必须有一个默认的构造方法;
2,在Spring中,配置的每一个bean其实是一个实例;
3,根据配置的class,调用的是Class.forName(“class”)).newInstance()---->newClass....
所以,Spring其实就是把本来应该写在代码中的初始化代表移动到XML中了;
(7)Spring中bean的名称:
1,Spring中的模块管理:
在Spring中,如果大量的类都配置在一个配置文件中,难以管理,可以按照模块,把bean配置在不同的XML中,并使用主的配置文件来引入这些模块的配置文件;
2,Spring中的bean的名称:
(8)Spring中的测试:
之前的测试存在的问题:
1,每一个测试方法,都需要手动启动Spring;相当于Spring容器是运行在测试类的方法中的;
2,每一个测试方法,都需要手动启动Spring,还需要正常的关闭Spring;
3,各个模块的配置文件混淆在一起;
Spring中的测试,不仅仅是提供了更好的测试方式,在Spring的测试包中,还包括了很多Mock对象,还有用于事务控制的测试或者集成测试等很多辅助的测试工具;
步骤:
1,拷包(替换默认的eclipse的JUNIT环境;拷贝context.jar,expression.jar,aop.jar)
2,在类上使用@RunWith
3,在类上使用@ContextConfiguration;
4,在类中使用@Autowire标签放在BeanFactory属性上;
5,在测试代码中,只需要直接从BeanFactory获取bean即可;
(9)容器:
1,Spring中最简单的,最基础的容器 BeanFactory;
在BeanFactory中,提供了一些最基本的容器的方法;最重要的就是提供了从容器中拿对象的方法;
因为BeanFactory提供的功能太简单了,所以平时开发时很少使用;
2,Spring中最常用的容器:ApplicationContext
1,ApplicationContext继承了BeanFactory接口,所以,ApplicationContext也提供了最基本的拿bean的方法;
2,ApplicationContext在BeanFactory的基础之上,提供了更多的应用所需的功能:
1,容器环境的感知;
2,bean的继承;
3,国际化;
4,Spring的事件机制;
5,统一的资源处理;
6,AOP;
3,ApplicationContext的使用:
1,在Springtest中的使用(在使用Spring-test的时候,启动的本来就是ApplicationContext容器):
2,手动创建ApplicationContext容器;
(10)Spring中在不同容器下,bean的初始化时机;1,BeanFactory是在真正去拿bean的时候,才会去创建bean的实例(延迟实例化);
2,ApplicationContext是在容器启动的时候就已经创建好了bean的实例(迫切实例化);
延迟实例化的优势:应用启动的时候占用的资源很小;适合资源紧张的应用;
迫切实例化的优势:应用在启动的时候已经实例化所有的对象,就可以在启动的时候发现对象的错误或者为这些对象做更多的事情(比如AOP);
建议Web应用中,就使用迫切加载;
当然,也可以在bean上面添加lazy-init=true来让ApplicationContext也延迟实例化对象;
还可以在beans上面配置default-lazy-init=true让整个beans中所有的bean全部延迟实例化;
(11)Spring中bean的实例化方式:bean是怎么创建出来的.
1,bean使用默认的构造方法创建:
2,静态工厂方法;
配置文件:
拿bean:
3,实例工厂方法:
配置文件:
拿bean:
4,Spring内置的工厂类;
1,创建一个工厂类,实现FactoryBean接口;
2,配置:
3,获取bean:
(12):spring处理factorybean的过程:
1,先从classpath下加载Spring的配置文件;
2,使用配置文件创建一个ApplicationContext对象;
1,遍历配置文件中所有的bean元素;
2,根据bean元素的class属性去创建一个对象的实例(Class.forName(“class”)).newInstance();
3,判断当前创建的对象是否是一个FactoryBean的实例;
3.1如果不是,继续向下执行
3.2是一个FactoryBean接口;
1,先把这个实例+&id存放到容器中;
2,FactoryBean bean=(FactoryBean)instance;
然后调用bean.getObject()创建一个实例,然后再把这个实例+id存放到容器中;
3,把创建好的实例+bean元素中的id存放到容器中;
3,使用getBean方法的时候,就是按照查询(getBean)的方式,从容器中找到合适的bean的实例并返回;
4,总结:如果一个类继承了Spring中提供的内部的某一个接口,当我把这个类配置在Spring容器中,这个类就有了一些Spring特殊的功能;
(13)****Bean的Scope:1,默认情况下,Spring中的bean都是单例的;
2,可以通过bean的scope属性来配置对象的生命周期范围
1,default/singleton:默认的配置,代表bean是单例的
2,prototype:
把scope设置为prototpe,每次得到的对象都是一个全新的对象;
prototype类型的bean,在容器启动的时候不会创建,只会在每次从容器拿对象的时候,才会创建;
3,request:在一次请求中创建一个对象,必须依赖HTTP环境
session:在一次会话中创建一个对象,必须依赖HTTP环境
3,什么时候使用prototype?线程不安全的对象交给Spring管理,就必须设置为prototype,比如struts2的Action;
(14)Bean的初始化方法和销毁方法:1,有的时候,在bean初始化完成之后,还要调用一些初始化方法才能让bean处于立刻可用状态;
2,有的时候,在spring正常关闭,销毁bean的时候,需要调用bean的一些销毁方法来正常释放资源;
3,可以通过bean上面的init-method和destory-method来配置
4,注意,init-method和dstory-method都不能有参数;
5,如何手动正常关闭Spring容器?
a:
b:
6,多例的对象是不会调用destory-method的;
(14)IOC容器
(15)什么叫DI(Dependence inject),依赖注入
对象的属性关系由spring来管理;对象的属性由Spring来设置;
两种注入方式:
1,使用Setter注入(使用属性的对应的setter方法来注入,要求set方法);
2,使用构造器注入
(16)使用setter注入:
1,简单类型;
2,某一些复杂类型;
1,从spring配置文件中得到的值(value能够配置的值)都是String类型的,但是针对某些类型,Spring内部可以直接把String类型转化对应的类型;
2,Spring的转型依赖PropertyEditor;
3,其他的bean;
4,集合; 1,list 2,set 3,map 4,properties 集合注入在一般情况下面不会使用,一般是一些框架相关的bean才会使用到;
(17)构造方法注入:
1,如果在bean中没有配置constructor-arg参数,则spring会使用对象默认的无参构造方法实例化对象;
2,如果在bean中配置了constructor-arg参数,spring会使用这些constructor-arg去唯一确定一个构造方法,并使用这个构造方法创建对象实例;
确定构造方法?
1,默认情况下,constructor-arg的顺序就是构造方法参数的顺序(在实际使用中,推荐就按照默认的方式来设置值即可);
2,三种方式可以调整构造方法参数的顺序:
1,index:通过构造方法参数位置来指定;从0开始;
2,type:在构造方法中参数的类型;
3,name:使用构造方法参数的名字来设置;
(18)setter VS 构造方法注入
1,使用setter和构造方法都能够正确的注入bean的属性;
2,构造方法可以更强制的规定依赖的对象必须存在,如果不配置,则创建对象失败;但是构造方法不宜有过多的参数,否则代码难以维护;
3,更多的还是使用setter方式的注入,但是setter注入可能会产生忘记配置的问题,可以使用@Required注解来配置;