发表于: 2018-01-31 22:54:13
2 522
今天做的事情:
复习之前所学。
Spring框架:
- 低侵入式设计,代码的污染极低。
- 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺。
- Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦。
- Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。
- Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。
- Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。
管理bean :
程序主要是通过Spring容器来访问容器中的Bean,ApplicationContext是Spring容器最常用的接口,该接口有如下两个实现类:
- ClassPathXmlApplicationContext: 从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器。
- FileSystemXmlApplicationContext: 从文件系统的相对路径或绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器。
理解依赖注入:控制反转IOC 依赖注入DI
当某个Java对象(调用者)需要调用另一个Java对象(被依赖对象)的方法时,在传统模式下通常有两种做法:
- 原始做法:
- 调用者主动创建被依赖对象,然后再调用被依赖对象的方法。
- 简单工厂模式: 调用者先找到被依赖对象的工厂,然后主动通过工厂去获取被依赖对象,最后再调用被依赖对象的方法。
注意上面的主动二字,这必然会导致调用者与被依赖对象实现类的硬编码耦合,非常不利于项目升级的维护。使用Spring框架之后,调用者无需主动获取被依赖对象,调用者只要被动接受Spring容器为调用者的成员变量赋值即可,由此可见,使用Spring后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受——所以Rod Johnson称之为控制反转。
容器中Bean的作用域:
1. singleton :单例模式,在整个springIOC容器中,singleton作用域的Bean将只生成一个实例。
2.prototype : 每次通过容器的getBean()方法获取prototype作用域的Bean,都讲产生一个新的Bean实例。
3.request : 对于一次HTTP请求,request作用域的Bean都会生产一个实例。这意味着在一次请求之内,每次请求,都会得到同一个实例。
4.对于一次HTTP会话,session作用域的Bean将只生成一个实例,这意味着,在同一次HTTP会话内,程序每次请求该Bean,得到的总是同一个实例。只有在Web应用中使用Spring时,该作用域才真正有效。
5. global session: 每个全局的HTTP Session对应一个Bean实例。在典型的情况下,仅在使用portlet context的时候有效,同样只在Web应用中有效。
如果不指定Bean的作用域,Spring默认使用singleton作用域。prototype作用域的Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成果,就可以重复使用。因此,应该尽量避免将Bean设置成prototype作用域。
关于Bean的自动装配:
autowire
和default-autowire
可以接受如下值:
no
: 不使用自动装配。Bean依赖必须通过ref元素定义。这是默认配置,在较大的部署环境中不鼓励改变这个配置,显式配置合作者能够得到更清晰的依赖关系。byName
: 根据setter方法名进行自动装配。Spring容器查找容器中全部Bean,找出其id与setter方法名去掉set前缀,并小写首字母后同名的Bean来完成注入。如果没有找到匹配的Bean实例,则Spring不会进行任何注入。byType
: 根据setter方法的形参类型来自动装配。Spring容器查找容器中的全部Bean,如果正好有一个Bean类型与setter方法的形参类型匹配,就自动注入这个Bean;如果找到多个这样的Bean,就抛出一个异常;如果没有找到这样的Bean,则什么都不会发生,setter方法不会被调用。constructor
: 与byType类似,区别是用于自动匹配构造器的参数。如果容器不能恰好找到一个与构造器参数类型匹配的Bean,则会抛出一个异常。autodetect
: Spring容器根据Bean内部结构,自行决定使用constructor或byType策略。如果找到一个默认的构造函数,那么就会应用byType策略。
搜索Bean类
Spring提供如下几个Annotation来标注Spring Bean:
@Component
: 标注一个普通的Spring Bean类@Controller
: 标注一个控制器组件类@Service
: 标注一个业务逻辑组件类@Repository
: 标注一个DAO组件类
在Spring配置文件中做如下配置,指定自动扫描的包:
<context:component-scan base-package="edu.shu.spring.domain"/>
Spring的AOP
AOP也就是面向切面编程,专门用于处理系统中分布于各个模块中交叉关注点的问题,在JavaEE应用中,常常用于AOP来处理一些具有横切性质的系统级服务,如事务管理,安全检查,缓存,对象池管理、
使用AspectJ实现AOP
AspectJ是java语言的AOP框架,提供了强大的AOP功能。
关于面向切面编程的一些术语:
- 切面(Aspect): 切面用于组织多个Advice,Advice放在切面中定义。
- 连接点(Joinpoint): 程序执行过程中明确的点,如方法的调用,或者异常的抛出。在Spring AOP中,连接点总是方法的调用。
- 增强处理(Advice): AOP框架在特定的切入点执行的增强处理。处理有"around"、"before"和"after"等类型
- 切入点(Pointcut): 可以插入增强处理的连接点。简而言之,当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。
下面是spring.xml中关于AOP的事务,切面,日志。
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 编写通知:对事务进行增强,需要对切入点和具体执行事务细节 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- <tx:method> 给切入点添加事务详情
name:方法名称, *表示任意方法, do* 表示以do开头的方法
propagation:设置传播行为
isolation:隔离级别
read-only:是否只读 -->
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
<!--ISOLATION_DEFAULT 默认级别(对大多数数据库来说就是ISOLATION_READ_COMMITTED)-->
<!--ISOLATION_READ_UNCOMMITTED 最低的隔离级别。事实上我们不应该隔离级别,因为在事务完成前,其他事务可以看到该事务所修改的数据。
而在其他事务提交前,该事务也可以看到其他事务所做的修改。-->
<!--ISOLATION_READ_COMMITTED 大多数数据库的默认级别。在事务完成前,其他事务无法看到该事务所修改的数据。
遗憾的是,在该事务提交后,你就可以查看其他事务插入活更新的数据。这意味着在事务的不同点上,如果其他事务修改数据,你会看到不同的数据。-->
<!--ISOLATION_REPEATABLE_READ 该隔离级别确保如果在事务中查询了某个数据集,你至少还能再次查询到相同的数据集,即使其他事务修改了所查询的数据。
然而如果其他事务插入了新数据,你就可以查询到该新插入的数据。-->
<!--ISOLATION_SERIALIZABLE 代价最大、可靠性最高的隔离级别,所有的事务都是俺顺序一个接一个的执行。-->
</tx:attributes>
</tx:advice>
<!-- aop编写,让Spring自动对目标进行代理,需要使用AspectJ的表达式 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* com.jnshu.serviceImpl.AccountServiceImpl.*(..))" id="txPointCut"/>
<!-- 切面:将切入点和通知整合 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
<!-- 配置日志打印类 -->
<bean id="logHandler" class="com.jnshu.handler.LogHandler"/>
<aop:config>
<!-- order属性表示横切关注点的顺序,当有多个时,序号依次增加 -->
<aop:aspect id="log" ref="logHandler" order="1">
<!-- 切入点为AccountServiceImpl类下的transfer方法 -->
<aop:pointcut id="logTime" expression="execution(* com.jnshu.serviceImpl.AccountServiceImpl.transfer(..))"/>
<aop:before method="LogBefore" pointcut-ref="logTime"/>
<aop:after method="LogAfter" pointcut-ref="logTime"/>
<aop:around method="around" pointcut-ref="logTime"/>
</aop:aspect>
</aop:config>
遇到的问题:
看资料看的还有点蒙,一天下来还是没记住多少。
收获:
梳理了一下spring的基础知识,了解Quartz任务调度框架
评论