Java框架学习之Spring
什么是spring
- Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
- 轻量级:与EJB对比,依赖资源少,销毁的资源少。
- 分层: 一站式,每一个层都提供解决方案
web层:struts,spring-MVC
service层:spring
dao层:hibernate,mybatis , jdbcTemplate --> spring-data
spring优点
|
spring体系结构
核心容器:beans、core、context、expression
IoC
控制反转(Inverse of Control),将对象交给Spring管理,包括对象的创建和销毁
新建项目导入jar包:
4 + 1 : 4个核心(beans、core、context、expression) + 1个依赖(commons-loggins...jar)
测试:
配置文件:
- 位置:任意,开发中一般在classpath下(src)
- 名称:任意,开发中常用applicationContext.xml
- 内容:添加schema约束
约束文件位置:spring-framework-5.0.8.RELEASE/docs/spring-framework-reference/core.html打开找一下
applicationContext.xml
接口和实现类
测试:
DI
Dependency Injection ,依赖注入,即一个类中组合了其他的类对象,可以通过配置Spring为其赋值,称之为依赖注入
配置文件:
类调用关系
测试代码没变,只是输出变成了 addUser dao
核心API
BeanFactory :这是一个工厂,用于生成任意bean。采取延迟加载,第一次getBean时才会初始化Bean
ApplicationContext:是BeanFactory的子接口,功能更强大。(国际化处理、事件传递、Bean自动装配、各种不同应用层的Context实现)。当配置文件被加载,就进行对象实例化。
ClassPathXmlApplicationContext 用于加载classpath(类路径、src)下的xml
加载xml运行时位置 --> /WEB-INF/classes/...xml
FileSystemXmlApplicationContext 用于加载指定盘符下的xml
加载xml运行时位置 --> /WEB-INF/...xml
可以通过java web ServletContext.getRealPath() 获得具体盘符
测试以上两个对象初始化对象方式的不同:
ClassPathXmlApplicationContext:
BeanFactory:
输出空
添加beanFactory.getBean("user");后执行
装配bean
基于XML
3种bean实例化方式:默认构造、静态工厂、实例工厂
默认构造
必须要有默认无参构造器
静态工厂
- 常用与spring整合其他框架(工具)
- 静态工厂:用于生成实例对象,所有的方法必须是static
<bean id="" class="工厂全限定类名" factory-method="静态方法">
例如:
配置
工厂:
测试:
实例工厂
必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的。
配置
工厂:
测试:
Bean种类
- 普通bean:之前操作的都是普通bean。<bean id="" class="A"> ,spring直接创建A实例,并返回
- FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象。
bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean。
<bean id="" class="FB"> 先创建FB实例,使用调用getObject()方法,并返回方法的返回值
FB fb = new FB();
return fb.getObject();
- BeanFactory 和 FactoryBean 对比?
BeanFactory:工厂,用于生成任意bean。
FactoryBean:特殊bean,用于生成另一个特定的bean。例如:ProxyFactoryBean ,此工厂bean用于生产代理。<bean id="" class="....ProxyFactoryBean"> 获得代理对象实例。AOP使用
作用域:用于确定spring创建bean实例个数
取值:
singleton 单例,默认值。
prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。
配置信息
<bean id="" class="" scope=""> |
测试:
默认为单例
多例:
输出
生命周期
- 初始化和销毁
- 目标方法执行前后执行后,将进行初始化或销毁。
<bean id="" class="" init-method="初始化方法名称" destroy-method="销毁的方法名称"> |
配置文件:
测试:
作用域改为多例的
没有输出:说明(1)多例对象在调用时才初始化(包括构造函数和初始化方法)
(2)多例的对象销毁方法在容器关闭时不被调用
BeanPostProcessor 后处理Bean
1.spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前后执行下面两个方法 配置<bean class="">
2.spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。
实现类:
配置:
测试:
后处理bean被实现并交给Spring后默认将会作用于容器中所有的类
可以添加beanName属性使其只作用于某个类:
属性依赖注入
- 依赖注入方式:手动装配 和 自动装配
- 手动装配:一般进行配置信息都采用手动
基于xml装配:构造方法、setter方法
构造方法注入:
User提供了三个构造方法:
(1)根据构造函数参数名称注入
xml配置:
测试:
输出:
User [name=jack, age=21, id=0]
(2)根据构造函数参数索引和类型注入
其它方式,例如仅仅根据类型或索引注入的方式只要不冲突也可以
只要提供了可用的构造方法就可以删去无参构造
Setter方法注入:
setter方法:
测试:
输出:
UserDaoImpl [user=User [name=jack, age=21, id=0]]
SpEL[了解]
对<property>进行统一编程,所有的内容都使用value
<property name="" value="#{表达式}">
#{123}、#{'jack'} : 数字、字符串
#{beanId} :另一个bean引用
#{beanId.propName} :操作数据
#{beanId.toString()} :执行方法
#{T(类).字段|方法} :静态方法或字段
待续。。。
基于注解装配:
自动装配:struts和spring 整合可以自动装配
byType:按类型装配
byName:按名称装配
constructor构造装配,
auto: 不确定装配。