Spring 框架的构成
IOC 控制反转 它是Spring框架的核心
DAO 数据访问对象模块 它是对JDBC的封装和简化
WebMVC 它是Spring 对 java web的支持 以及 MVC设计模式的支持
AOP 面向切面编程 它是对面向对象的扩展
ORM 对象关系映射(是以面向对象的思想访问数据库) Mybatis
什么是IOC?
Inverstion Of Control 控制反转
程序中需要某个对象时 由原来的new的方式 改成了由容器来进行 创建 和 管理 以及维护组件关系。
这样做的好处是 可以大大降低组件之间的耦合度。
Spring 容器
任何的java 类 都可以在Spring容器中创建对象 并由容器进行管理 以及维护组件关系
Spring容器实现了 IOC 和 AOP 机制
Spring 容器的类型 BeanFactory 或者是 ApplicationContext类型
使用Spring容器 完成IOC的步骤
1 建立一个项目 导入jar包(ioc相关jar包) 拷贝Spring配置文件到src下
2 在SPring配置文件中 配置对象创建的说明
<bean id="对象的引用名" class="包名.类名"> </bean>
3 创建Spring 容器对象 创建对象时需要指定配置文件 使用对应的API 获取对象
---- 以从容器中获取一个日期对象为例
Spring 容器创建对象的三种方式
1 构造器方式实例化
<bean id="标识符" class="包名.类名"> </bean>
默认调用类型对应的无参构造方法
2 静态工厂方法实例化
本质上是类型调用对应的静态方法 来获取一个对象 类型名.静态方法名()
比如在java 代码中创建一个 Calendar 类型的对象
<bean id="标识符" class="包名.工厂类名" factory-method="静态方法名"> </bean>
3 实例工厂方法实例化
本质上是利用一个已经存在的对象 来创建出另外一个类型的对象
<bean id="标识符" factory-method="实例方法名" factory-bean="工厂对象的id"> </bean>
Spring 中对象的作用域
Spring 中 对象默认的作用域 是 单例的 如果希望每次请求 都获取不同的对象 则可以使用 bean标记中的 scope 属性指定作用域。
scope 默认的取值是 singleton 设置成 prototype 则为非单例的。 当然这里也有request session 等作用域 这到web部分才会涉及。
Spring 容器中的对象的初始化和销毁
1 初始化
一个对象被容器创建之后 可以通过 beans标记中的 default-init-method 属性来指定初始化方法,由于这样影响的范围比较大(影响配置文件中所有的对象)
所以对象对应的类型中如果没有对应的初始化方法程序也不会报错。也可以通过bean 标记中的init-method 属性来指定初始化方法,这种方式 只会影响到一个对象
所以对象对应的类型中如果没有对应的初始化方法程序就会报错。
2 销毁
当一个对象即将消亡时 可以通过 beans标记中的 default-destroy-method 属性来指定销毁方法,由于这样影响的范围比较大(影响配置文件中所有的对象)
所以对象对应的类型中如果没有对应的销毁方法程序也不会报错。也可以通过bean 标记中的destroy-method 属性来指定销毁方法,这种方式 只会影响到一个对象
所以对象对应的类型中如果没有对应的销毁方法程序就会报错 但是销毁方法只针对单例模式的对象。
bean 对象的延迟实例化
在Spring 容器中 对象默认的作用域是单例的 Spring容器对单例对象 默认是容器启动时创建
可以通过bean 标记的 lazy-init="true" 让其使用到的时候创建容器启动时不创建。
<bean id="card" class="entity.Card" />
<bean id="card" class="entity.Card" lazy-init="true"/>
什么是DI?
Dependence Injection 依赖注入(依赖注射)
把一个组件的值 设置给另外一个组件的过程 叫依赖注入
DI解决的问题就是组件的装配问题
DI的三种实现方式
1 setter 注入
参考类型对应的set方法 来进行值的设置
在bean 标记中 出现如下配置 <property name="属性名" value="值" > </property>
属性名 这是设置值 所以参考的是 set方法去掉set 然后首字母小写
如果要赋值复杂的值 则需要使用 ref, value 能赋值的类型有 八种基本类型 和 封装类 String 枚举
2 构造器注入
参考的是构造方法的参数 只要构造方法的参数能匹配上 则直接调用对应的带参构造
在bean 标记中 出现如下配置 把上面的 property 标记 换成 constructor-arg
注意我们可以使用 index 替换 name,index 代表参数的编号 编号0开始
3 自动化注入
主要解决复杂值的注入问题
只要在bean 标记中 使用 autowire 属性 指定自动化注入的方式即可
autowire 的取值有 byName byType constructor
byName 参考的是属性名
byType 参考的是成员变量的类型
constructor 参考的是构造方法
参数的注入
1 简单值的注入
简单值包括 八种基本类型 和 对应的封装类 String 枚举
使用连接池的jar包 创建 dataSource 对象 使用容器获取数据源对象(连接池对象) 并通过这个对象获取数据库连接
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"></property>
<property name="username" value="liziyang"></property>
<property name="password" value="123"></property>
</bean>
2 复杂值的注入
把set注入 或者构造器注入中的 value 改成 ref 或者自动化注入
3 集合参数的注入
java 中有 List Map Set Properties 可以在Spring 配置文件中 配置对应的标记 让其创建出对应的对象
<property name="friends">
<list>
<value>果</value>
<value>冻</value>
<value>无</value>
<value>敌</value>
</list>
</property>
<property name="people">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
<value>3</value>
</set>
</property>
........
集合参数的单独定义
一个集合参数可以被单独定义出来 然后让其他对象的属性 进行引用
例如
<util:list id="ref_list">
<value>果</value>
<value>冻</value>
<value>无</value>
<value>敌</value>
</util:list>
<util:set id="ref_set">
<value>1</value>
<value>2</value>
<value>3</value>
<value>3</value>
</util:set>
<bean id="msgBean2" class="entity.MsgBean">
<property name="friends" ref="ref_list"></property>
<property name="people" ref="ref_set"></property>
</bean>
Spring 的EL表达式
和之前的区别是 从Spring 容器中取值 语法是 把之前的$换成 #
以 dbcp.properties 为例子
<util:properties id="ref_db" location="classpath:dbcp.properties"></util:properties>
<bean id="msgBean2" class="entity.MsgBean">
<property name="content" value="#{ref_db.username}"></property>
</bean>