spring 回顾
主要就是它的IOC理念
即:把对象的创建、初始化、销毁等工作交给spring容器来做
依赖jar
通过spring的IOC容器获取bean,执行对应的方法
圈中的内容会启动spring容器,加载spring配置文件,加载过程中会初始化配置文件中对应的bean(用bean的类中的构造函数初始化了对象)
关于注解请看:
http://www.cnblogs.com/luotuoke/p/4544144.html
说明:
1、 启动spring容器
2、 spring容器内部会自动创建有注释(@Servic,@Controller,@Repository,@Component)的对象
3、 当spring容器解析到
启动依赖注入的注解解析器:
4、 看哪些bean的属性上面是否有Resource(@Autowired)注解
5、 如果属性上面有该注解,再次检查是否有name属性
6、 如果没有name属性,则会把该注解标注的属性的名称获取到和spring容器中的id做匹配,如果匹配成功,则赋值,如果匹配不成功,则按照类型进行匹配,如果匹配成功,则赋值,如果匹配不成功,则报错。
7、 如果有name属性,则把name属性的值解析出来和spring容器中的id做匹配,如果匹配成功,则赋值,如果匹配不成功,则报错。
8、 从上述的步骤可以看出注解的效率比较低,xml的效率比较高,注解书写比较简单,xml书写比较复杂。
@Service 用于标注业务层组件,注意得注释在实现类中,不要注释在接口上。在action中引用时用的是接口,这种bean默认是“singleton”的。
例如:
@Autowired 后不需要getter()和setter()方法,spring也能够自动注入
当然除了注解方式的生成bean和注解,也可以通过配置文件方式
在spring的相关配置文件中如下写法:
由于上面的类HelloWorldFactory中的getInstance方法是静态的所以不用实例化对象去调用,用类名可直接调用
当想要执行对应的上面构造的对象的方法时,根据bean的Id
执行此对象的方法
凡是有scope=prototype的,都会出现延迟加载(加载spring容器时对应的bean类不会去构造对象),并且lazy-init的false失效
如果把lazy-init设置为true,则当spring容器启动的时候,检测不到任何错误,这样会存在很大的安全性隐患,所以一般情况下应该设置lazy-init为default/false。但是如果一个bean中有一个属性,该属性含有大量的数据,
这个时候不希望该bean过早的停留在内存 中。这个时候需要用到lazy-init为true。
在默认情况下放入到spring中的bean是单例的
将来service层和dao层所有的类将放入到spring容器中,所以默认情况下这两个层的类的实例都是单例的,所以不能把数据声明到属性中。如果声明在属性中,将会成为共享的。
可以想象 ,javabean等封装数据的类是不能放在spring容器中的。
action的视图层类来接收数据的类,为啥要设计成多例(@scope),原因就在于此吧。
1, 加载spring配置文件时,调用默认的构造函数为每个bean创建一个对象(在非layz-init=true时)。
2, 如果含有di(对象的属性赋值操作),为初始化的对象赋值
3, Bean中声明了init-method方法,执行此方法
4, 执行getBean()
5, 执行方法
说明:
1、 init方法是由spring内部执行的
2、 只有当spring容器关闭以后才能执行destroy方法,spring容器一般情况下是不会关闭的。只有当web容器销毁掉的时候才可能关闭掉,所以只要一个对象在spring容器中,在spring容器关闭之前,会一直保留。
3、 如果一个bean的配置是scope为”prototype”,则spring容器不负责销毁。
与注解方式的对比:
当getBean(”person”)时就会去访问容器在扫描类时在内存中解析到的<bean id=”person” >(解析的过程中会根据注释的Component在内存中生成bean,然后根据resource找到bean并对其相关联的属性进行赋值)
的对象,然后就可访问其方法了。
流程分析
1、 启动spring容器
2、 Spring容器解析类扫描的注解解析器,在base-package指定的包及子包中查找所有的类
3、 查看哪些类上面是否含有@Component注解
4、 如果该注解的value的属性的值为空,则把类名的第一个字母变成小写,作为id值,放入到spring容器中
5、 如果该注解的value的属性的值不为空,则用value的属性的值作为id值,放入到spring容器中
6、 再次查找在spring容器中的类的所有的属性,按照@Resource的规则给属性赋值
说明
使用了类扫描机制的做法,配置文件中的配置很简单了,但是效率越来越低。
spring的东西貌似很多的样子
简略的写一下 面试可能会问的东西:
IOC:控制反转(Inversion of Control),将对象的创建,初始化,销毁等工作都交给spring容器;
你在spring的配置文件(applicationContext.xml)中配置了对应的bean那么就会在加载spring配置文件的时候就去实例化这个bean的对象(注解方式则不用去配置,会根据注解去实例化)(排除延迟加载的情况scope=”prototype”或lazy-init=”true”)。
spring容器实例化bean的三种方式
构造函数
静态工厂是调用的静态方法 所以不需要工厂的对象
实例工厂要创建对象得调用非静态放,所以先得到工厂的对象 用这个对象去调用方法
DI:主要体现在依赖注入(给属性赋值)方面: 如果要注入的属性是对象,在bean中配置property=”beanid”,利用java的反射机制调用要注入的属性的set方法赋值,或者直接根据注释注入属性对象
把action调用service,service调用dao等对象的创建交给spring来完成
非注解方式的话:
注解方式的话:
实现了完全的面向接口编程,在代码端没有必要关心一个接口的实现类是什么。
Aop: 经典的面向切面编程,其底层原理是动态代理。
在开发中的一些日志记录,事务,异常处理等都可以看成是aop的切面。
以spring的声明自己的事务处理为例子,beginTrasaction();就是一个前置通知,commit()就是一个后置通知,其中还有环绕通知,能够控制切入点(目标方法)是否执行。异常通知等。
切面<aop:aspect,,,>中配置的方法会伴随着切入点表达式<aop pointcut,expression=”packge.*.*”,>中的方法。
配置事物管理器:对目标方法进行事物管理,当在执行目标方法时,出现异常,则目标方法中的操作数据库的语句是不会提交的。
事物实例:
为什么要用事物举例;
应用层面的事务是在业务级的,这种事务数据库管不着。要是一个应用没有事务,自己点点刷刷是没有问题的,但真正到生产环境中就不一定行了。
比如你去银行取钱,银行把钱给你,然后在你帐户中把你的余额修改,这是一个事务的,能保证你拿到钱后去你再去查你的帐户,你能立刻看到你的账户余
额减少,如果没有事务,你可能去查看到的余额没有变,你会有什么感觉。这只是很简章的一方面。
可以用作权限,可以决定目标方法是否执行
ProceedingJoinPoint join
Object obj = join.proceed();//决定代理对象的调用方法(连接点)是否执行,,obj为连接点的返回值。
aop的优劣
(1).好处:
1).在编写service的时候,不用管譬如权限之类的业务要求
2).切面负责除了业务逻辑的其他内容,而且切面中的通知(权限控制)和业务逻辑方法没有任何关系,做到了完全松耦合
3).最后产生的代理对象吧通知和目标结合在一起
(2).不好之处
切入点和通知相互交织,有复杂的嫌疑。并不像struts那样具有像栈一样的模块
SSH的整合:与hibernate,在spring配置文件中配置产生dataSource的bean(有数据库配置信息)
配置产生sessionFactory的bean,sessionFactory依赖dataSource
在dao实现类声明sessionFactory对象(这个dao继承了HibernateDaoSuport)
与struts的结合 ,action的产生交给了spring容器;
1、 服务器启动通过web.xml的ContextLoaderListener监听器类,
1) 并且调用ContextLoaderListener监听器的contextInitialized()方法,在其中调用了createContextLoader()方法实例化了一个ContextLoader的contextLoader对象。
2) 用这个ContextLoader对象去加载spring的配置文件
首先在web.xml中找<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/applicationContext.xml
如果有此配置则根据此配置来加载spring配置文件,没有则默认去加载web-info/applicationContext.xml(此方法不推荐)
3) 继续用contextLoader对象调用它的initWebApplicationContext()方法,
在此方法中用createWebApplicationContext()创建了WebApplicationContext容器(spring容器),并将此容器放到了servletContext域中(web应用域)。
在此容器中实例化dao,service等一些实例化对象。
-----------------------===================================
通过StrutsPrepareAndExecuteFilter过滤器
调用此过滤器的init()方法//在此init方法中用InitOperations的对象init去调用InitOperations的initDispatcher()方法
此init()方法执行过程中加载了default.properties文件(包含一些常量信息比如同一编码,默认utf-8,还有文件上传的默认大小为2M,都有默认值,但都是可以改变的)
struts-default.xml(配置了启动struts容器时默认加载的一些jar包,结果集类型定义,默认拦截器的声明,拦截器栈的声明,要加载好多bean这也是struts容器启动慢的原因)、
struts-plugin.xml(改写了action的生成方式,改为按照StrutsSpringObjectFactory 里的buildAction方式生成action)、这里的声明将action的创建交给了spring容器
struts.xml文件
2、 当url请求时通过StrutsPrepareAndExecuteFilter过滤器
调用都doFiler()方法执行过程中
首先利用容器启动时创建的对象prepare和execute
1) 调用(default.priperties)的配置(文件中的struts编码默认UTF-8)设置编码
2) 创建了值栈valuestack
3) 初始化值栈,将request,session,application对象放入到值栈中的map栈中
4) 还创建了一个actionContext,将valuestack值栈中的map栈赋值给actionContext的context,所以值栈中map栈与actionContext中的context存在着同一个引用。
5) 将actionContext放入到了当前线程(threadLocal)中,保证线程的一致性
6) 创建action代理(与struts有所不同)
7) 创建action,将action放到栈顶
8) 执行action代理的invoke()方法
9) 顺序执行配置的所有拦截器
10)执行所需的action中的方法,执行结果集(反馈给浏览器),倒序执行拦截器
11)清空struts容器中的数据环境(清空了actionContext中的所有数据)
当结合spring容器后,创建action的方式发生了改变,
当用户请求道action时,
根据struts.xml中对应action配置的class=””值去在spring容器找bean的name值(这个actionbean配置了scope=”prototype”,一般此项必须配置,不然可能形成数据共享,这样确保多个action操作的不是同一个实例),创建action对象
其他过程不变
spring 回顾的更多相关文章
- Spring回顾
1.IOC和DI IOC:Inversion of Control(控制反转)是一个重要的面对对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心. IOC理解:将组件对象的控 ...
- 一篇教你看懂spring bean工厂和aop
这篇文章为spring回顾总结的第二篇,本篇主要分为两个部分,分别是spring的bean工厂的实现.spring的aop实现原理,这两部分也是面试当中问的比较多的. spring的bean工厂的实现 ...
- mybaits(七)spring整合mybaits
与 Spring 整合分析 http://www.mybatis.org/spring/zh/index.html 这里我们以传统的 Spring 为例,因为配置更直观,在 Spring 中使用配置类 ...
- Java回顾之Spring基础
第一篇:Java回顾之I/O 第二篇:Java回顾之网络通信 第三篇:Java回顾之多线程 第四篇:Java回顾之多线程同步 第五篇:Java回顾之集合 第六篇:Java回顾之序列化 第七篇:Java ...
- Spring day04笔记(SVN讲解和回顾昨天知识)
spring day03回顾 事务管理 基于xml配置 1.配置事务管理器 jdbc:DataSourceTransactionManager hibernate:HibernateTransacti ...
- Spring知识点回顾(08)spring aware
Spring知识点回顾(08)spring aware BeanNameAware 获得容器中的bean名称 BeanFactoryAware 获得当前的bean factory Applicatio ...
- Spring知识点回顾(07)事件发布和监听
Spring知识点回顾(07)事件发布和监听 1.DemoEvent extends ApplicationEvent { public DemoEvent(Object source, String ...
- Spring知识点回顾(01)Java Config
Spring知识点回顾(01) 一.Java Config 1.服务和服务注入 2.Java 注解 :功能更强一些 3.测试验证 二.注解注入 1.服务和服务注入 2.配置加载 3.测试验证 三.总结 ...
- 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)
一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...
随机推荐
- 中缀表达式转逆波兰式(后缀表达式)求值 C++ Stack
给一个包含小数的中缀表达式 求出它的值 首先转换为后缀表达式然后利用stack求出值 转换规则: 如果字符为'(' push else if 字符为 ')' 出栈运算符直到遇到‘(' else if ...
- mysql实例的连接数max_user_connections 和max_connections 配置的那些事
今天在查线上问题时,通过phpMyAdmin来进行DML操作,发现比平时慢多了,就各种进原因. 项目的场景是一个mysql实例中创建了多个数据库,猜想可能是相互影响所致. 然后,查询线上Mysql数据 ...
- Javascript控制回车键进行表单(form)提交(转)
一.采用钩子事件去捕获 键盘事件有3个: keydown,keypress,keyup分别是按下,按着没上抬,上抬键盘 . $(document).keyup(function(event){ if( ...
- Spring MVC-集成(Integration)-生成PDF示例(转载实践)
以下内容翻译自:https://www.tutorialspoint.com/springmvc/springmvc_pdf.htm 说明:示例基于Spring MVC 4.1.6. 以下示例显示如何 ...
- [转]十五天精通WCF——第十二天 说说wcf中的那几种序列化
我们都知道wcf是由信道栈组成的,在我们传输的参数走到传输信道层之前,先需要经过序列化的过程,也就是将参数序列化为message,这篇 我们就来说说这里的序列化,蛮有意思的,可能初学者也明白,在wcf ...
- servlet 中getLastModified()
在http协议中,浏览器对访问过的页面缓存后,它将会在以后访问该页面时,将会根据LastModified头字段指定的时间值生成If-Modified-Since头字段,作为缓存页面的最新更新时间.如果 ...
- W5500中断寄存器的理解
W5500中断部分,W5500中文手冊V1.0 写的不够清楚,该文是本人结合中英文手冊及自己理解,整理出有关中断部分的理解,如有不对的请指正. 一:引脚 INTn 为中断输出(Interrupt ou ...
- footer在最低显示
footer在最低显示 http://stackoverflow.com/questions/585945/how-to-align-content-of-a-div-to-the-bottom
- linux openssl 编程 Client端
相关配置等请參看上一篇关于server端文章:http://blog.csdn.net/pingd/article/details/47805349 1.Client端源代码: openssl_cli ...
- 将byte[]转为各种进制的字符串
/** * 将byte[]转为各种进制的字符串 * @param bytes byte[] * @param radix 基数可以转换进制的范围(2-36),从Chara ...