Spring组成
Spring IOC
Spring容器
- 在Spring中,任何的Java类都被当成Bean 组件,通过容器管理和使用。
- Spring容器实现了IOC和AOP机制
- Spring容器有ApplicationContext和 BeanFactory两种类型
- 建议使用ApplicationContext
Bean对象的创建
spring容器创建Bean对象的三种方法
- 使用构造器来实例化
//构造器配置 Bean组件定义格式
<bean id=“标识符" class=“包名.类名"/> - 使用静态工厂方法实例化
//静态工厂方法配置 Bean组件定义格式
- 使用实例工厂方法实例化
//动态工厂方法配置 Bean组件定义格式
从ApplicationContext容器中获取Bean组件
类型 变量名 = 容器对象 . getBean (“ 标识符 ”, 组件类型 )
Bean对象的作用域
Bean对象初始化、销毁、延迟实例化
指定Spring容器中创建Bean对象初始化
<beans default-init-method=“初始化方法名">
<bean id="标识符" class="类“/>
</beans>
或者
<beans>
<bean id="标识符" class="类“ init-method =“初始化方法名"/>
</beans>
指定Spring容器中创建Bean对象初始化
<beans default-destroy-method=“销毁方法名">
<bean id="标识符" class="类“/>
</beans>
或者
<beans>
<bean id="标识符" class="类“ destroy-method =“销毁方法名"/>
</beans>
Bean对象的延迟实例化
默认情况下,容器对象创建时Bean对象就会 创建,可以指定实例化延迟
<beans default-lazy-init=“true">
<bean id="标识符" class="类“/>
</beans>
或者
<beans>
<bean id="标识符" class="类” lazy-init=“true"/>
</beans>
DI依赖注入
Bean参数注入
注入字符串
<bean id="msg" class="com.xdl.bean.OracleDataSource">
<property name=“username" value=“scott"/>
<property name=“password“ ><value>tiger</value> <property>
<property name=“msg“ > <null/> </property>
</bean>
通过、、
Map集合注入
<bean id="demo" class="com.xdl.bean.DemoBean">
<property name="score">
<map>
<entry key=“1001" value=“99"/>
<entry key=“1002" value=“100"/>
<entry key="1003" value="98"/>
</map>
</property>
</bean>
Properties集合注入
<bean id="demo" class="com.xdl.bean.DemoBean">
<property name=“dbParams">
<props>
<prop key="user">scott</prop>
<prop key="password">tiger</prop>
</props>
</property>
</bean>
引入注入集合
List、Set、Map、Properties集合也可以先 独立定义,再注入的方式使用,这样便于重 复利用。
<util:list id=“subjectList">
<value>php</value>
<value>java</value>
</util:list>
<bean id=“demo" class="com.xdl.bean.DemoBean">
<property name=“subjects" ref=" subjectList"/>
</bean>
Spring表达式注入
<util:properties id=“db“ location="classpath:db.properties"/>
<bean id="demo" class="com.xdl.bean.OracleDataSource">
<property name=“username" value="#{db.name}"/>
<property name=“password" value="#{db.password}"/>
<property name=“url" value="#{db.url}"/>
</bean>
组件扫描
Spring提供了一套基于注解配置的使用方法。 使用该方法可以大大简化XML配置信息.
开启组件扫描
-
在applicationContext.xml添加启动标记
<context:component-scan base-package=“包路径”/> -
在组件类中添加注解
-
扫描组件后,默认scope为singleton单例, 也可以进行指定,例如
@component(“empDao”)
@Scope(“prototype”) -
也可以指定初始化和销毁的方法
例如
@Component
public class DemoBean {
@PostConstruct
public void init() {
//初始化回调方法
}
@PreDestroy
public void destroy() {
//销毁回调方法
}
} -
将所有Bean组件扫描到Spring容器后,可 以使用以下注解指定注入关系
@Autowired/@Qualifier
可以处理构造器注入和Setter注入
@Resource
只能处理Setter注入,但大部分情况都是Setter注入
Spring AOP
通知的五大类型
1.前置通知aop:before 目标方法调用之前
2.后置通知aop:after-returning 目标方法不抛异常,并且执行完才调用
3.最终通知aop:after目标方法调用完成调用,但无视异常
4.环绕通知aop:around目标方法调用前后都执行
5.异常通知aop:after-throwing出现异常才进行通知
通知对应的标注:
@Before 前置通知
@AfterReturning 后置通知 抛出异常不会执行
@After 最终通知 抛出异常也会执行
@AfterThrowing 异常通知 抛出异常才执行
@Around 环绕通知
切点表达式
类型限定表达式
within(包名.类名)
within(com.xdl.Service.XdlAccountService)限定一个具体的类
within(com.xdl.Service.XdlAccount*)支持模糊限定
within(com.xdl.Service.)代表Service包下所有类型切入切面逻辑
within(com.xdl..)多个包的模糊匹配,xdl下的直接子包下类型
within(com.xdl…)xdl下所有包下类型都切入逻辑
方法限定表达式
execution(权限 返回值 方法名(参数) 异常)
返回值 方法名()必须有!
execution(* log*()) 返回值不受限制 支持模糊查询
execution(log(int))返回值不受限制 方法名必须以log开头,参数int类型
注意方法名前面可以有包名.类名
bean的id限定
bean(容器中组件的id作为匹配的标准,可以使用模糊匹配)
Spring DAO
- DAO(Data Access Object)数据访问对象
- Spring DAO为整合JDBC提供了封装,简化了DAO组件的编写
- Spring DAO提供了AOP模式的事务处理
- Spring DAO提供了统一的异常处理层次,它包装的异常类型DataAccessException 继承自RuntimeException无须显式的捕 获
Spring整合JDBC
JDBCTemplate提供的主要方法:
queryForInt()
queryForObject()
query()
update()
execute()
JDBCTemplate配置:
Spring事务
声明式事务管理
Spring声明式事务管理,是使用Spring的 AOP方式实现的
- 通过Spring配置将操作纳入到事务管理中
- 解除了事务管理和代码的耦合
- 不需要事务管理时,可直接从Spring配置文件 中移除
使用步骤
-
第一步: 在applicationContext.xml中声明事务组件,开启事务注解扫描
<tx:annotation-driven transaction-manager=“txManager” proxy-target-class=“true”/> -
第二步: 使用@Transactional注解声明事务
@Transactional属性
propagation:设置事务传播 默认:REQUIRED
isolation:设置事务隔离级别 默认:事务隔离级别是DEFAULT,根据数据库自动选择,Oracle默认READ_COMMITED级别
readOnly:设置为只读,还是可读写 默认readOnly=false
rollbackFor:设置遇到哪些异常必须回滚(默认:任何RuntimeException将触发事务回滚,但是任何Checked Exception将不触发事务回滚 )
noRollbackFor:设置遇到哪些异常不回滚
**脏读:**一个事务读取到了另外一个事务没有提交的数据
**不可重复读:**一个事务在开始时读取了一份数据,然后再事务操作的过程中另外一个事务修改了这份数据并进行了提交,当第一个事务再次读取这份数据时,发现数据发生了改变.
**幻读:**一个事务对一张表中的所有数据做了统计,但是这个时候发生了数据的增加,再次统计数据发现数据发生了改变.
propagation 事务的传播特性####
一个方法(可能有也可能没有)调用一个事务方法时的表现
- REQUIRED 如果当前方法没有事务,则创建一个事务,如果当前方法有事务则加入到当前事务中.
- Propagation.MANDATORY 表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常
- Propagation.NESTED 表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像Propagation.REQUIRES一样。
- Propagation.NEVER 表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。
- Propagation.NOT_SUPPORTED 表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。
- Propagation.SUPPORTS 表示当前方法不需要事务性上下文,但是如果有一个事务已经在运行的话,它也可以在这个事务里运行。
- Propagation.REQUIRES_NEW 表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。
- Propagation.REQUIRED 表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。
Spring MVC
SpringMVC应用结构
将控制器数据传输给页面
1 使用request session application等这些域对象传递数据
2 使用ModelAndView来进行数据传递,ModelAndView对象可以通过getModel()得到map接口类型模型
,也可以通过getModelMap()得到一个ModelMap类型的模型.
3 使用ModelMap来传递数据
mm.addattribute();
mm.put();
4 使用Model 来传递数据
5 @ModelAttribute(“abc”)可对复杂对象进行模型key的设置,默认
对类名首字母小写之后放入request作用域中.
Spring MVC中重定向
Spring MVC中默 认对请求进行转发处理,如要实现重定向,则需用以下两种方式
1 针对控制器方法 返回String
"redirect:重定向路径"
2 针对控制器方法 返回ModelAndView
RedirectView rv = new RedirectView("toMain2.do");
ModelAndView mav = new ModelAndView();
mav.setView(rv);
控制器中的中文参数处理
spring中是通过编码过滤器解决的
//注意它只针对post方式
<filter>
<filter-name></filter-name>
<filter-class></filter-class>
</filter>
<filter-mapping>
<filter-name></filter-name>
<url-pattern></url-pattern>
</filter-mapping>
拦截器
实现步骤:
-
写一个类,先实现HandlerInterceptor接口
-
配置拦截器 拦截器组下可配置多个拦截器
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*"></mvc:mapping> <bean class="com.xdl.interceptor.checkLogin"></bean> </mvc:interceptor> </mvc:interceptors>
-
多个拦截器的执行顺序
preHandler 执行顺序和配置顺序一致
其它方法和 配置顺序相反
Spring MVC中的异常处理
1 当程序中出现了异常,使用SimpleMappingExceptionResolver来处理,只需要在配置文件中配置这个对象即可
<!--配置出项的异常类型和错误页面之间的对应关系-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.NullPointException">error1</prop>
<prop key="java.lang.Exception">error2</prop>
</props>
</property>
</bean>
2 第二种异常处理方案
实现HandlerExceptionResolver接口
3 局部异常处理
针对的是一个具体的控制器,控制之外的异常处理不了
@ExceptionHandler加在控制器中的一个自定义方法上
文件上传
1 写一个文件上传页面
请求方式:post
enctype="multipart/form-data"
包含文件上传的file组件
2 写文件上传的控制器
控制器解析文件上传的请求,需借助MultipartResolver接口实现
借助第三方jar包
<!--配置一个文件解析器-->
<bean id="MultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
REST
REST即表述性状态传递(英文:Representational State Transfer,简称REST)
对请求的URL做了基于资源的设计
对请求方式做了设置 用 GET POST PUT DELETE 代表对应的操作
RESTful
基于REST规范的应用程序就是RESTful
@PathVariable作用是将URI请求模板中的变量解析出来,映射到处理方法的参数上
RESTful对静态资源放行
DispatcherServlet 对应的url-parttern 改成 /
需要对静态资源放行 <mvc:default-servlet-handler/>
Spring ORM
Mybatis
Apache开源项目IBatis后迁移给Google code更名为MyBatis
可以做SQL操作(增删改DML 查DQL DDL)以及存储过程的调用
ORM(对象关系映射 把数据库中的数据变成对象,以及组织对象之间的关系)
MyBaties 封装了几乎所有的JDBC操作以及参数的手工设置以及结果集的检索和对象的封装2.
Mapper映射器规则
1.SQL定义文件中的namespace要和接口的包名.接口名保持一致
2.接口中的方法名和sql定义文件中sql语句id保持一致
3.方法的参数要和parameterType中规定的一致
4.方法的返回值要和resultType保持一致
DML(insert delete update)返回值可以是void也可以是int
select语句最多返回单行 方法的返回值类型和resultType一致
select语句可返回多行 方法的返回值类型要是List
MyBatis应用扩展
${}和#{}参数区别
- ${}采用Statement机制;#{}采用PrepareStatement预编译SQL执行机制
- 建议采用#{},能防止注入式攻击,安全
- 表名和字段名位置使用${},动态sql;字段值位置使用#{}
Mapper映射器多参数映射问题
- 使用#{param1}、#{param2}…
- 推荐使用@Param(“key”)然后使用#{key}
自定义类型别名
在sqlmap-config.xml中追加定义
<typeAliases>
<typeAlias type="cn.xdl.entity.Dept" alias="dept"/>
</typeAliases>
开启MyBatis框架日志输出
在sqlmap-config.xml中追加定义
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
MyBatis分页处理
- 添加pageHelper.jar开发包
- 在sqlmap-config.xml中追加定义
- 使用方法,在调用Mapper方法查询前执行
Page page = PageHelper.startPage(1, 3);
List list = deptDao.findAll();