<返回更多

spring框架史上最全深入理解

2019-08-12    
加入收藏

spring框架

1.spring是一个轻量级的控制反转和面向切面aop的容器框架

控制反转:ioc

spring框架史上最全深入理解

 

核心容器:

1.应用上下文 context模块:

2.aop模块:

3.jdbc抽象和dao模块

4.对象关系映射集成模块

5.spring web模块

6.spring mvc框架

spring ioc控制反转和di依赖注入

ioc:即控制反转,不是什么技术,而是一种设计思想,在JAVA开发中,ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制;在传统java se的程序设计,为们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而ioc是有专门的一个容器来创建这些对象,即由ioc容器来控制对象的创建;

反转:传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮助创建及注入依赖对象;因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;依赖对象的获取被反转了。

ioc能做什么:

ioc不是一种技术,只是一种思想。一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合,更优良的程序,传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了ioc容器后,吧创建和查找依赖对象的控制交给了容器;有容器进行诸如组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

ioc和di:

di-dependency injection 即 ‘依赖注入’ 组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态将某个依赖注入到组件之中,依赖注入的目的并非为软件系统带来更多功能,而是为提升组件重要的频率,并为系统搭建一个灵活,可扩展的平台,通过依赖注入机制,我们只需要通过简单的配置,而无需要任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关系具体的资源来自何处,由谁实现。

“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”

spring bean工厂和工厂bean 分析

bean工厂:不是bean,在spring中一般指的是DefaultListableBeanFactory对象,管理和维护spring中所有的bean

工厂bean:一种特殊的bean,在xml文件中配置的,用来生成新的bean的加工厂,通过getObject()方法可以获取其生产的新bean,如果想获取该工厂bean本身,需要使用类似于getBean("&" + beanName)的样式。

<bean name="studentFactory" class="com.demo.StudentFactoryBean" />

Spring常用的三种注入方式

1.构造方法注入:

2.setter注入:

3.基于注解的注入:

构造方法注入:

在spring的配置文件中注册UserService,将UserDaoJdbc通过constructor-arg标签注入到UserService的某个有参数的构造方法
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
	<constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>
通过name属性指定要注入的值,与构造方法参数列表参数的顺序无关。
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
	<constructor-arg name="userDao" ref="userDaoJdbc"></constructor-arg>
	<constructor-arg name="user" ref="user"></constructor-arg>
</bean>
<!-- 注册实体User类,用于测试 -->
<bean id="user" class="com.lyu.spring.entity.User"></bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>

基于注解的注入:

bean的一个属性autowire,autowire主要有三个属性值:constructor,byName,byType。

constructor:通过构造方法进行自动注入,spring会匹配与构造方法参数类型一致的bean进行注入,如果有一个多参数的构造方法,一个只有一个参数的构造方法,在容器中查找到多个匹配多参数构造方法的bean,那么spring会优先将bean注入到多参数的构造方法中。

byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写,这一点与手动set注入有点不同。

byType:查找所有的set方法,将符合符合参数类型的bean注入。

注解方式注册bean,注入依赖

主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:

@Component:可以用于注册所有bean

@Repository:主要用于注册dao层的bean

@Controller:主要用于注册控制层的bean

@Service:主要用于注册服务层的bean

描述依赖关系主要有两种:

1.@Resource

2.@Autowired

@Resource java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean。

@Resource
@Qualifier("userDaoMyBatis")
private IUserDao userDao;
public UserService(){
}

@Autowired:spring注解,默认是以byType的方式去匹配类型相同的bean,如果只匹配到一个,那么就直接注入该bean,无论要注入的 bean 的 name 是什么;如果匹配到多个,就会调用 DefaultListableBeanFactory 的 determineAutowireCandidate 方法来决定具体注入哪个bean。determineAutowireCandidate 方法的内容如下:

determineAutowireCandidate 方法的逻辑是:

先找 Bean 上有@Primary 注解的,有则直接返回 bean 的 name。

再找 Bean 上有 @Order,@PriorityOrder 注解的,有则返回 bean 的 name。

最后再以名称匹配(ByName)的方式去查找相匹配的 bean。

可以简单的理解为先以 ByType 的方式去匹配,如果匹配到了多个再以 ByName 的方式去匹配,找到了对应的 bean 就去注入,没找到就抛出异常。

还有一点要注意:如果使用了 @Qualifier 注解,那么当自动装配匹配到多个 bean 的时候就不会进入 determineAutowireCandidate 方法(亲测),而是直接查找与 @Qualifer 指定的 bean name 相同的 bean 去注入,找到了就直接注入,没有找到则抛出异常。

tips:大家如果认真思考可能会发现 ByName 的注入方式和 @Qualifier 有点类似,都是在自动装配匹配到多个 bean 的时候,指定一个具体的 bean,那它们有什么不同呢?

ByName 的方式需要遍历,@Qualifier 直接一次定位。在匹配到多个 bean 的情况下,使用 @Qualifier 来指明具体装配的 bean 效率会更高一下。

spring 支持三种创建bean

1.调用构造器创建bean;

2.调用静态工厂方法创建bean;

3.调用实例工厂方法创建bean;

ioc底层原理:dom4j+反射

反射一定会走无参构造函数;

反射原理 加载配置xml配置文件,解析xml文件,bean的几点, 初始化bean id class=是全路径;

拿到beanid 去容器中

spring容器的 bean的作用域:

1.singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护;

2.prototype:原型范围与单例范围相反,为每一个bean请求提供一个实例;

3.request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会消失并被垃圾回收;

4.session:与请求范围类似,确保每一个session中有一个bean的实例,在session过期后,bean会随之失效;

5.global_session: global_session 和portlet应用相关,当你的应用部署在portlet容器中工作时,他包含很多portlet,如果你想要声明让所有的portlet公用全局的存储的话,那么这全局变量需要存储在global_session中。

springmvc 和 struts2比较

spring框架史上最全深入理解

 

1.springMVC的入口是servlet,而struts2是filter;

2.springmvc 会比struts2快些,springmvc是基于方法设计,而sturt2是基于类,每次发一次请求都会实例一个action;

3.springmvc 使用更加简洁,开发效率springmvc比struts2高;

spring 事务管理器:

spring并不是直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给hibernate或者jta等待持久化机制所提供的相关平台框架的事务来实现;

spring 事务: 1.编程式事务控制; jdbc代码 hibernate事务

声明事务:spring 声明式事务管理,核心实现就是基于aop

spring声明式是为管理类:

jdbc技术:DataSourceTransactionManager

Hibernate技术:HibernateTransationManager

spring session

spring框架史上最全深入理解

 

web.xml 配置filter: springSessionRepositoryFilter

spring的七种事物传播行为:

PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

aop底层实现原理:

代理设计模式:通过代理控制对象的访问,可以想象访问某个对象方法,在这个方法调用处理,或者调用后处理,aop的核心技术面相切面编程;

@Aspect 指定一个类为切面类

@Pointcut("execution(* com.itmayiedu.service.UserService.add(..))") 指定切入点表达式

@Before("pointCut_()") 前置通知: 目标方法之前执行

@After("pointCut_()") 后置通知:目标方法之后执行(始终执行)

@AfterReturning("pointCut_()")返回后通知: 执行方法结束前执行(异常不执行)

@AfterThrowing("pointCut_(_()") 异常通知: 出现异常时候执行

@Around("poinrcut_()") 环绕通知:环绕目标方法执行

@before("execution(* com.muth.service.userservece.add(..))")

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>