Spring框架(一)
Spring概念
Spring框架:项目中对象的容器.帮我们管理以及维护项目中的所有对象.
- 帮我们创建对象,并维护对象间的依赖关系.
- 整合了代理技术,实现了AOP思想.
完成事务管理,日志管理,权限管理… - spring本身也可以整合几乎任何第三方框架,作为项目中的粘合剂,spring项目组增加也提供很多功能对象来扩展spring功能.
一站式框架
Spring框架搭建
导包
- 核心容器包(4个)(beans、context、core、expression)
- 日志包(2个)(log4j、commons)
创建一个类
创建JavaBean,set/get方法。
创建spring配置文件
导入约束
1. 创建application.xml放置在src目录下
2. schema文件导入spring-context-4.2.xsd,key type 选 Schema location
3. 编辑名称空间,从Specify New Namespace 中选取 spring-context-4.2.xsd,名称空间截取名称之前的字符串,Prefix不填。
将User对象交给spring管理
<bean name="user" class="cn.it.domain.User"></bean>
代码测试
1. 创建spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
2. 从容器中获得管理的对象
User user = (User) context.getBean("user");
spring相关概念
IOC&DI
IOC:Inverse Of Control 反转控制
spring框架改变开发人员以往创建对象的方式
以往创建方式:任何对象都右开发人员手动创建
spring:帮我们创建对象
相比以往,对象的创建方式被反转,右开发人员创建反转为由程序帮我们创建.
DI: Dependency Injection 依赖注入
依赖注入是一种技术的名词.
该技术可以将对象依赖的属性注入到对象中.
spring创建对象时,需要使用DI技术来注入依赖关系(属性).
DI实现:
1.构造注入
2.set方法注入
IOC与DI关系:实现IOC思想需要依赖DI技术
BeanFactory&ApplicationContext
BeanFactory接口
BeanFactory是spring框架初代接口
BeanFactory是ApplicationContext父接口
BeanFactory是获得对象时才创建对象.
ApplicationContext接口
ApplicationContext是后期发展出的接口
ApplicationContext的功能要更加强大
ApplicationContext是启动时默认立刻创建容器中所有对象,获得时直接返回
spring配置详解(xml)
基本配置
bean元素:将对象交给spring容器管理
name属性:给管理的对象起个名字.获得时根据该名字获得.
id属性:给管理的对象起个名字.获得时根据该名字获得.
name属性与id属性区别:
1.id出现时间较早.
2.id属性必须符合id规范:唯一不能使用特殊字符.
3.name属性:可以重复(不推荐),也可以使用特殊字符.
class属性:要管理的对象的完整类名.
scope属性:决定对象作用域,对象生命周期
singleton(默认值):单例,容器启动时创建单例对象,容器销毁时才销毁单例对象
prototype:原型多例,启动时不会创建,每次获得时都会创建新的对象,对象不会放入容器的管理.
request:web环境下的属性,对象的生命周期为一次请求.
session:web环境下的属性,对象的生命周期为一次会话.
init-method | destory-method属性
指定对象的生命周期方法.
init-method:指定对象的初始化方法,会在构造方法调用之后调用.
destory-method:指定对象的销毁方法,会在容器销毁对象之前调用.
注意:prototype对象spring不会调用销毁方法.
<bean name="user" class="cn.it.domain.User" scope="singleton"
destroy-method="destory" init-method="init" ></bean>
spring创建对象方式
调用构造方法创建对象
applicationContext.xml文件配置
<!-- 1.构造方法注入 -->
<bean name="user" class="cn.it.domain.User" >
静态工厂创建
user对象的创建时调用UserFactory的getUser方法创建
public static User getUser(){
System.out.println("静态工厂创建对象");
return new User();
}
applicationContext.xml文件配置
<!-- 2.静态工厂创建对象
user2对象的创建是调用UserFactory的getUser方法.
-->
<bean name="user2" class="cn.it.create.UserFactory" factory-method="getUser"></bean>
动态工厂创建
调用userFactory对象的getUser方法获得User对象.
public User getUser2(){
System.out.println("动态工厂创建对象");
return new User();
}
applicationContext.xml文件配置
<!-- 3.动态工厂创建对象
user3对象的创建是调用UserFactory的getUser2方法.
-->
<bean name="userFactory" class="cn.it.create.UserFactory" />
<bean name="user3" factory-bean="userFactory" factory-method="getUser2"></bean>
spring中的DI(依赖注入)
构造方法注入
constructor-arg:指定构造参数
定位属性:
name属性:参数名
index属性:指定参数在参数列表中的索引
type属性:指定参数类型
注入属性:
value属性:参数值
ref属性:注入引用类型
<!-- 1.构造方法注入 -->
<bean name="user" class="cn.it.domain.User" >
<!-- 一个参数 -->
<constructor-arg name="name" value="张三"></constructor-arg>
<!-- 两个参数 -->
<constructor-arg name="name" value="李四"></constructor-arg>
<constructor-arg name="age" value="18" type="java.lang.Integer" ></constructor-arg>
<constructor-arg name="car" ref="car" ></constructor-arg>
</bean>
</bean>
set方法注入
property标签
property元素:调用一个set方法.
<bean name="user2" class="cn.it.domain.User">
<!-- propert元素:代表调用一个set方法 -->
<property name="name" value="王五"></property>
<property name="age" value="40"></property>
<property name="car" ref="car"></property>
</bean>
p名称空间注入
对比property标签:p名称空间写法更加简单,p出现较晚.
引入xmlns:p="http://www.springframework.org/schema/p"
<bean name="user3" class="cn.it.domain.User" p:name="赵六" p:car-ref="car" p:age="22"></bean>
SPEL表达式
SPEL:spring expression language spring 表达式语言
注意:只能引用属性,不能引用对象.
<bean name="user4" class="cn.it.domain.User">
<!-- propert元素:代表调用一个set方法 -->
<property name="name" value="#{user.name}"></property>
<property name="age" value="#{user.age}"></property>
<property name="car" ref="car"></property>
</bean>
spring复杂类型注入
Array
向数组中注入值
1.只需要向数组中注入一个元素
<property name="arr" value="hello"></property>
2.向数组中注入多个元素
<property name="arr">
<array>hehe</array>
<ref bean="car" />
</property>
List
向List中注入值
1.只需要向List中注入一个元素
<property name="list" ref="car"></property>
2.向List中注入多个元素
<property name="list">
<list>
<value>hehe</value>
<ref bean="car"/>
</list>
</property>
Map
向Map中注入值
<property name="map">
<map>
<entry name="xixi" value="haha"></entry>
<entry name="james" value-ref="car"></entry>
<entry name-ref="gife" value-ref="car"></entry>
</map>
</property>
Properties
向Properties中注入值
<property name="prop">
<prop>
<prop key="user">root</prop>
<prop key="password">abc</prop>
</prop>
</property>
spring配置(注解)
使用注解代替xml配置
准备工作
导包
spring-aop jar包导入约束
spring-context-4.2.xsd开启注解开关
base-package属性:指定扫描那个包中的注解,指定包以及子孙包都会扫描
注解
注册对象
@Component(“user”)
@Repository(“user”)
@Service(“user”)
@Controller(“user”)
指定对象作用域
@Scope(“singleton”)
指定对象生命周期
@PostConstruct
@PreDestory
注入值类型
@Value(“”)
//对成员变量赋值,不走set方法
@Value("宝马")
private String name;
@Value("红色")
private String color;
//调用Set方法完成赋值
@Value("宝马")
public void setName(String name) {
this.name = name;
}
注入引用类型
//方式1,自动装配
@Autowired //自动根据要注入的类型,从容器中获得对应对象
//方式2,自动装配+辅助
@Autowired
@Qualifier(“”)
//方式3,手动根据name装配
@Resource(name=”“)
//方式一:自动根据要注入的类型,从容器中获得对应的对象.
@Autowired
//方式二:@Qualifier告诉自动装配哪个名字的车
@Autowired
@Qualifier("car2")
//方式三:直接使用@Resource指定将哪个对象注入属性
//@Resource(name="car2")
private Car car;
将spring应用到项目中
导包
导入(4+2)+spring-web包
写配置文件
配置spring容器随项目启动
原则:一个web项目启动只创建一个spring容器.
操作:
方案一:将spring容器的创建放入静态代码块中.该访问属于自己手动创建容器,容器与web项目没有关联,不推荐.
方案二:spring利用监听器(ServletContext对象创建与销毁监听器)来创建容器.
在web.xml中配置
<!-- 配置spring容器随项目启动监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 指定spring配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
获得spring容器及容器中对象
public CustomerAction() {
//获得容器=>从Application域获得容器
//1获得Application域对象
ServletContext sc = ServletActionContext.getServletContext();
//2调用工具方法从域中取出容器
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sc);
//3获得CustomerService
cs= (CustomerService) ac.getBean("customerService");
}
spring整合JDBC(JDBCTemplate)
spring框架提供一个可以完成jdbc操作的对象,该对象可以放置到spring容器中.
spring准备的操作数据库的类,与QueryRunner类的设计与使用几乎完全相同.
准备工作
导包
- spring-jdbc jdbc-tx
- 数据库驱动 c3p0连接池
常用API
- 增删改
jt.update(String sql,Object… params) - 查询单个值,并指定返回值类型
jt.queryForObject(String sql,Class requiredType,Object… params) - 查询,手动封装结果到对象中.返回单个对象
jt.queryForObject(String sql,RowMapper rm,Object… params) - 查询,手动封装结果.返回List
jt.query(String sql,RowMapper rm,Object… params)
JDBCSupport
继承JDBCSupport好处:可以减少一级依赖关系.直接将连接池对象注入给Dao即可
public class UserDao extends JdbcDaoSupport{
//继承JdbcDaoSupport类之后,省略,源码中已经帮我们实现
private JdbcTemplate jt;
public void setJt(JdbcTemplate jt) {
this.jt = jt;
}
使用DB.properties管理连接信息
准备Db.properties
jdbc.jdbcUrl=jdbc:mysql:///jdbc jdbc.driverClass=com.mysql.jdbc.Driver jdbc.user=root jdbc.password=123
spring配置中读取
<!-- 指定读取db.properties中的键值对 --> <context:property-placeholder location="classpath:db.properties"/>
在配置中引用
<!-- 连接池 --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean>