共计 8422 个字符,预计需要花费 22 分钟才能阅读完成。
1、IOC 和 DI
IOC: 管制反转
即控制权的转移,将咱们创建对象的形式反转了, 以前对象的创立是由咱们开发人员本人保护, 包含依赖关系也是本人注入。应用了 spring 之后,对象的创立以及依赖关系能够由 spring 实现创立以及注入,反转管制就是反转了对象的创立形式,从咱们本人创立反转给了程序创立(spring)
DI: Dependency Injection 依赖注入
spring 这个容器中,替你治理着一系列的类,前提是你须要将这些类交给 spring 容器进行治理,而后在你须要的时候,不是本人去定义,而是间接向 spring 容器索取,当 spring 容器晓得你的需要之后,就会去它所治理的组件中进行查找,而后间接给你所须要的组件.
实现 IOC 思维须要 DI 做反对
注入形式: 1.set 形式注入 2. 构造方法注入 3. 字段注入
注入类型: 1. 值类型注入 2. 援用类型注入
益处:
1. 升高组件之间的耦合度,实现软件各层之间的解耦.
2. 能够使容器提供泛滥服务如事务管理音讯服务解决等等。当咱们应用容器治理事务时,开发人员就不须要手工 管制事务,也不须要解决简单的事务流传
3. 容器提供单例模式反对,开发人员不须要本人编写实现代码.
4. 容器提供了 AOP 技术,利用它很容易实现如权限拦挡,运行期监控等性能
5. 容器提供泛滥的辅助类,使这些类能够放慢利用的开发. 如 jdbcTemplate HibernateTemplate
2.applicationContext & BeanFactory 区别
BeanFactory 接口
(1) spring 的原始接口,针对原始接口的实现类性能较为繁多
(2)BeanFactory 接口实现类的容器,特点是每次在取得对象时才会创建对象
ApplicationContext 接口
(1) 每次容器启动时就会创立容器中配置的所有对象
(2) 提供了更多功能
(3) 从类门路下加载配置文件: ClassPathXmlApplicationContext
从硬盘的绝对路径下加载配置文件:FileSystemXmlApplication
3.spring 配置详解
3.1、元素属性
bean 元素: 应用该元素形容须要 spring 容器治理对象
name 属性: 给被治理的对象起个名字, 取得对象时 getBean(“name 值 ”)
class 属性: 被治理对象的残缺类名
id 属性: 与 name 属性截然不同,名称不可反复,不能应用特殊字符
name 和 id 之间的一些留神点:
1、配置两个雷同的 id 或者 name 都不能通过。
2、如果既配置了 id,也配置了 name,则两个都失效。如果 id 和 name 都没有指定,则用类全名作为 name,如 <bean class=”com.stamen.BeanLifeCycleImpl”>, 则你能够通过 getBean(“com.stamen.BeanLifeCycleImpl”)返回该实例。
3、如果配置根本类的时候,注解和配置文件都应用的时候,注解和配置文件中 name 雷同的时候,则两个抵触,配置文件失效。
如果配置根本类的时候,注解和配置文件都应用的时候,注解和配置文件中 name 不雷同的时候,则两个不抵触,都可能失效。
3.2、bean 元素进阶(scope 属性 生命周期属性)—————单例多例
(1)scope 属性
(1)singleton 默认值
单例对象 : 被标识为单例的对象在 spring 容器中只会存在一个实例
(2)prototype
多例原型: 被标识为多例的对象, 每次在取得才会被创立, 每次创立都是新的对象
(3)request
Web 环境下, 对象与 request 生命周期统一
(4)session
Web 环境下, 对象与 session 生命周期统一
总结: 绝大多数状况下,应用单例 singleton(默认值),然而在与 struts 整合时候,务必要用 prototype 多例,因为 struts2 在每次申请都会创立一个新的 Action,若为单例,在多申请状况下,每个申请找找 spring 拿的都是同一个 action。
(2)生命周期属性 (理解)———初始化和销毁
(1) 配置一个办法作为生命周期初始化办法,spring 会在对象创立之后立即调用 init-method
(2)配置一个办法作为生命周期的销毁办法,spring 容器在敞开并销毁所有容器中的对象之前调用 destory-method
<bean init-method=“init”destory-method=“destory”></bean> 对应注解为 @PostConstruct
<bean name=“hello”class=“残缺类名”></bean> 对应注解为 @PreDestory
(3)模块化配置, 即分模块配置(导入其余 spring 配置文件)
<beans>
<import resource =“spring 配置文件的全路径名”/>
</beans>
3.3、spring 三种对象的创立形式
(1)空参数结构 (重要)
(2) 动态工厂创立 (调用静态方法创立)
调用 UserFactory 类的动态 createUser 办法创立名为 user 的对象, 放入容器
<bean name="user" class="cn.itcats.UserFactory" factory-method="createUser"></bean>
(3)实例工厂创立(调用非静态方法创立)——须要配置两个 bean,因为无奈通过类名调用非静态方法
<bean name="user2" factory-bean="userFactory" factory-method="createUser"></bean>
<bean name=“userFactory”class=“cn.itcats.UserFactory”></bean>
3.4、spring 注入形式
(1)set 形式注入 (重点)————值类型用 value 注入 援用类型用 ref 注入
(2) 构造方法注入
函数注入
(3)p 名称空间注入———实际上 set 注入,spring 特有,为了简化 <property> 写法
1、applicationContext.xml 中 <beans> 标签头部导入 p 命名空间
xmlns:p="http://www.springframework.org/schema/p"
2、书写格局:值类型注入—— p: 属性名 =” 值 ” 援用类型注入—— p: 属性名 -ref=” 援用的 <bean> name 属性 ”
把 Run 类中的 name 属性值设置为 haha,age 属性设置为 20,援用属性 hello 援用 <bean name=”hello” class=”…”></bean>
<bean name="run2" class="cn.itcats.thread.Run" p:name="haha" p:age="20" p:hello-ref="hello"></bean>
(4)spel 注入: spring Expression Language spring 表达式语言
<bean name="runSpel" class="cn.itcats.thread.Run">
<!-- 取 bean 标签中 name 为 "user" 中 property 为 "name" 中的 value 值 --!>
<property name="name" value="#{user.name}"></property>
</bean>
SpEL 个性:(1)、应用 Bean 的 ID 来援用 Bean;(2)、调用办法和拜访对象的属性;(3)、对值进行算术、关系和逻辑运算;(4)、正则表达式匹配;(5)、汇合操作
对于 spel https://www.cnblogs.com/goodc…
简单类型注入
1.array 数组的注入
2.list 汇合的注入
3.map 汇合的注入
4.properties 的注入
4、避免创立多个 applicationContext 取值 / 并指定记录 spring 配置文件的地位——web.xml
1、须要导入包 spring-web
2、在 web.xml 中配置监听器
5、应用注解形式代替配置文件(官网举荐应用注解)
1. 在 applicationContext.xml 中书写指定扫描注解
2. 在类中书写 Component
留神:如果不写括号内的值(即 name 或 id),默认应用类名首字母小写作为搜寻,为什么意思呢?
比方 Student 类中应用了 @Component 没有书写括号和值,那么默认搜寻 id 或 name 为 student。
3. 指定对象的作用范畴 Scope
申明 Student 类对象为多例 上面是对 singleton 和 prototype 的一些补充
singleton 作用域:当把一个 Bean 定义设置为 singleton 作用域是,Spring IoC 容器中只会存在一个共享的 Bean 实例,并且所有对 Bean 的申请,只有 id 与该 Bean 定义相匹配,则只会返回该 Bean 的同一实例。值得强调的是 singleton 作用域是 Spring 中的缺省作用域。prototype 作用域:prototype 作用域的 Bean 会导致在每次对该 Bean 申请(将其注入到另一个 Bean 中,或者以程序的形式调用容器的 getBean()办法)时都会创立一个新的 Bean 实例。依据教训,对有状态的 Bean 应应用 prototype 作用域,而对无状态的 Bean 则应该应用 singleton 作用域。对于具备 prototype 作用域的 Bean,有一点很重要,即 Spring 不能对该 Bean 的整个生命周期负责。具备 prototype 作用域的 Bean 创立后交由调用者负责销毁对象回收资源。简略的说:singleton 只有一个实例,也即是单例模式。prototype 拜访一次创立一个实例,相当于 new。
4. 值类型的注入
理论通过反射 field 赋值
理论通过 set 形式赋值
5. 援用类型的注入
面试题: @AutoWired 和 @Resource 的区别?
@AutoWired 默认以类型进行查找,@Resource 默认以名称进行查找
@AutoWired(required=false) + @Qualifier(“user”) == @Resource(name=”user”)
其中 @Resource 注解是 jdk1.6 后才有的
6. 创立与销毁办法
7.spring 整合 junit 测试(spring 创立容器)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
6、spring 中 AOP 名词解释
JoinPoint(连接点): 指标对象中, 所有能够加强的办法,就是 spring 容许你是告诉(Advice)的中央,那可就真多了,根本每个办法的前、后(两者都有也行),或抛出异样是时都能够是连接点,spring 只反对办法连接点。Pointcut(切入点): 指标对象中, 曾经被加强的办法。调用这几个办法之前、之后或者抛出异样时干点什么,那么就用切入点来定义这几个办法。Advice(告诉 / 加强) : 加强办法的代码、想要的性能。Target(指标对象): 被代理对象,被告诉的对象,被加强的类对象。Weaving(织入): 将告诉利用到连接点造成切入点的过程
Proxy(代理): 将告诉织入到指标对象之后造成的代理对象
aspect(切面): 切入点 + 告诉————告诉 (Advice) 阐明了干什么的内容 (即办法体代码) 和什么时候干(什么时候通过办法名中的 before,after,around 等就能晓得),二切入点阐明了在哪干(指定到底是哪个办法),切点表达式等定义。
尽管当初都用 Maven 我的项目构建,然而不能遗记,应用 aop 须要用到的包:spring-aop + spring-aspects + springsource.org.aopalliance + springsource.org.aspectj.weaver
对于 AOP 看一个小例子:
1、筹备指标对象 (被代理对象,被告诉的对象,被加强的类对象)
2、筹备告诉(被加强办法的代码,想要实现性能的办法代码)
3、配置 applicationContext.xml
1. 导入 aop(束缚) 命名空间
2. 配置指标对象
3. 配置告诉对象
4. 配置将告诉织入指标对象
4、测试
总结:告诉的几种类型
1. 前置告诉———指标办法运行之前调用
2. 后置告诉———指标办法运行之后调用(如果出现异常不调用)
3. 盘绕告诉———指标办法之前和之后都调用
4. 异样拦挡告诉———如果出现异常,就会调用
5. 后置告诉———指标办法运行之后调用(无论是否出现异常都会调用)
7、spring 中的 aop 应用注解配置
1、applicationContext.xml 中配置指标对象,告诉对象,开启应用注解实现织入
2、@Aspect 注解代表该类是个告诉类,书写切点表达式 @Pointcut(“execution(返回值 全类名.
留神盘绕告诉须要这么写:
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// 盘绕办法执行前
//proceedingJoinPoint.proceed(); 示意对拦挡的办法进行放行
// 若正文 proceedingJoinPoint.proceed()则不会执行被 AOP 匹配的办法
proceedingJoinPoint.proceed();
// 盘绕办法执行后
AOP 注解解析:
@Before 前置告诉(Before advice):在某连接点(JoinPoint)——外围代码(类或者办法)之前执行的告诉,但这个告诉不能阻止连接点前的执行。为啥不能阻止线程进入外围代码呢?因为 @Before 注解的办法入参不能传 ProceedingJoinPoint,而只能传入 JoinPoint。要晓得从 aop 走到外围代码就是通过调用 ProceedingJionPoint 的 proceed()办法。而 JoinPoint 没有这个办法。这里牵扯区别这两个类:Proceedingjoinpoint 继承了 JoinPoint。是在 JoinPoint 的根底上暴露出 proceed 这个办法。proceed 很重要,这个是 aop 代理链执行的办法。暴露出这个办法,就能反对 aop:around 这种切面(而其余的几种切面只须要用到 JoinPoint,这跟切面类型无关),能决定是否走代理链还是走本人拦挡的其余逻辑。倡议看一下 JdkDynamicAopProxy 的 invoke 办法,理解一下代理链的执行原理。这样你就能明确 proceed 办法的重要性。@After 后告诉(After advice):当某连接点退出的时候执行的告诉(不论是失常返回还是异样退出)。@AfterReturning 返回后告诉(After return advice):在某连接点失常实现后执行的告诉,不包含抛出异样的状况。@Around 盘绕告诉(Around advice):突围一个连接点的告诉,相似 Web 中 Servlet 标准中的 Filter 的 doFilter 办法。能够在办法的调用前后实现自定义的行为,也能够抉择不执行。这时 aop 的最重要的,最罕用的注解。用这个注解的办法入参传的是 ProceedingJionPoint pjp,能够决定以后线程是否进入外围办法中——通过调用 pjp.proceed();
@AfterThrowing 抛出异样后告诉(After throwing advice):在办法抛出异样退出时执行的告诉。
8、spring 整合 jdbc
spring 中提供了一个能够操作数据库的对象,对象封装了 jdbc 技术 ————JDBCTemplate JDBC 模板对象,而 JdbcDaoSupport 则对 JdbcTemplate 进行了封装,所以要操作 JdbcTemplate,或只须要继承 JdbcDaoSupport 即可。
依赖关系配置:
测试:
9、spring 中的 aop 事务
事务的四大根本个性:
事物的概述
⑴ 原子性(Atomicity)原子性是指事务蕴含的所有操作要么全副胜利,要么全副失败回滚,因而事务的操作如果胜利就必须要齐全利用到数据库,如果操作失败则不能对数据库有任何影响。⑵ 一致性(Consistency)一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。拿转账来说,假如用户 A 和用户 B 两者的钱加起来一共是 5000,那么不论 A 和 B 之间如何转账,转几次账,事务完结后两个用户的钱相加起来应该还得是 5000,这就是事务的一致性。⑶ 隔离性(Isolation)隔离性是当多个用户并发拜访数据库时,比方操作同一张表时,数据库为每一个用户开启的事务,不能被其余事务的操作所烦扰,多个并发事务之间要互相隔离。即要达到这么一种成果:对于任意两个并发的事务 T1 和 T2,在事务 T1 看来,T2 要么在 T1 开始之前就曾经完结,要么在 T1 完结之后才开始,这样每个事务都感觉不到有其余事务在并发地执行。对于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。⑷ 持久性(Durability)持久性是指一个事务一旦被提交了,那么对数据库中的数据的扭转就是永久性的,即使是在数据库系统遇到故障的状况下也不会失落提交事务的操作。例如咱们在应用 JDBC 操作数据库时,在提交事务办法后,提醒用户事务操作实现,当咱们程序执行实现直到看到提醒后,就能够认定事务以及正确提交,即便这时候数据库呈现了问题,也必须要将咱们的事务齐全执行实现,否则就会造成咱们看到提醒事务处理完毕,然而数据库因为故障而没有执行事务的重大谬误。
对于事务的隔离级别我之前公布了一篇文章:https://blog.csdn.net/itcats_…
spring 中事务的分类:
spring 中事务能够分为编程式事务管制和申明式事务管制。
编程式事务管制
本人手动管制事务,就叫做编程式事务管制。
Jdbc 代码:
Conn.setAutoCommit(false); // 设置手动管制事务
Hibernate 代码:
Session.beginTransaction(); // 开启一个事务
【细粒度的事务管制:能够对指定的办法、指定的办法的某几行增加事务管制】
(比拟灵便,但开发起来比拟繁琐:每次都要开启、提交、回滚.)
申明式事务管制
Spring 提供了对事务的治理, 这个就叫申明式事务管理。
Spring 提供了对事务管制的实现。用户如果想用 Spring 的申明式事务管理,只须要在配置文件中配置即可;不想应用时间接移除配置。这个实现了对事务管制的最大水平的解耦。
Spring 申明式事务管理,外围实现就是基于 Aop。
【粗粒度的事务管制:只能给整个办法利用事务,不能够对办法的某几行利用事务。】
(因为 aop 拦挡的是办法。)
Spring 申明式事务管理器类:
Jdbc 技术:DataSourceTransactionManager
Hibernate 技术:HibernateTransactionManager
有一点须要留神的:若为编程式事务管制,则开启事务后肯定要手动开释(提交或回滚),否则长期占用内存,有可能报事务异样
spring 封装了事务管理的代码 (关上,提交,回滚事务)
事务操作对象, 因为在不同平台, 操作事务的代码各不相同.spring 提供了一个接口
————— PlatformTransactionManager 接口
————— 在不同平台, 实现不同的接口即可
————— 留神: 在 spring 中玩事务管理. 最为外围的对象就是 TransactionManager 对象
spring 治理事务的属性介绍
(1)事务的隔离级别
(2)是否只读
(3)事务的流传行为
配置事务的外围管理器,它封装了所有事务,依赖于连接池 (DataSourceTransactionManager)
xml 中配置告诉
配置将告诉织入指标
10、spring 中 aop 治理事务 注解应用步骤
在须要治理的办法或者类中申明配置事务管理
@Transactional(isolation=Isolation.REPEATABLE_READ,readOnly=false,propagation=Propagation.REQUIRED)